【PAT甲級筆記】常見知識點整理

知識篇:

1. 萬能頭文件

#include<bits/stdc++.h>

2. %lf %f的區別

lf爲雙精度浮點:(double)保證位數:15位
f爲單精度浮點:(float)保證位數:6位

3. 字符串的讀取 必備的頭文件:

 include <string>
include <cstring>
include <cstdio>

4.字符串的讀取使用的函數區別

  • getchar()

    1. 使用時爲: c=getchar(), 而非getchar( c); 但putchar()爲putchar( c) ;
  • scanf(“s”):

    1. 讀到\0結束
    2. 在用scanf讀取時,必須聲明長度。不聲明長度,直接scanf會出現運行時錯誤
  • cin.get(str,20)

  • getline(cin, str)
    (推薦使用類型,使用時str爲string 類型)

  • gets()

    1. 讀到換行符結束,並把\n替換成\0
    2. 這個函數我在刷的時候,使用會報編譯錯誤,似乎已經被c++14拋棄了,可以嘗試用cin.getline()或 getline(cin, )進行替換

用scanf時,使用string變量,必須申明長度,所以不建議使用scanf讀取string,可以用cin代替。

5.常用到的字符串縮減點:

  • strlen(): 計算長度,終止符’\0’不算在長度之內。取字符串長度要在for外面定義,否則會超時(已經被坑過了) 還有一點字符串從0開始
//容易超時的做法
for(int i=0;i<strlen(a);++i)
{
    //.....
}

//這樣可以減少計算時間
len=strlen(a);
for(int i=0;i<len;++i)
{
    //.....
}

5.讀取時,出現讀數字和字符交替情況:

由於scanf() 讀入數字時,無法讀入對應的\n,當需要再讀入字符串時,如getline()會直接讀入對應的\n,這樣會發生錯誤,解決辦法爲使用 scanf("%d\n", &n); 或者使用getchar()將對應的\n讀入。再使用getline()

//容易出問題的代碼
scanf("%d", &n);
getline(cin, c);

//解決的方法:
 scanf("%d\n", &n); 
 getline(cin, c);

//另一種方法:
getchar();
getline(cin, c);

6.字符串的讀取與輸出 sscanfsprintf

⽤⾮常好⽤的sscanfsprintf

  • sscanf() – 從⼀個字符串中讀進與指定格式相符的數據
  • sprintf() – 字符串格式化命令,主要功能是把格式化的數據寫⼊某個字符串中
等價類型:
b = atoi(a.c_str());
這裏的a爲string類型

等價類型
sscanf(a,"%d",b);
這裏的a需要爲char[]類型

6.find()函數的小知識

當使用STL時,如果使用a.find()函數,如果在查找範圍內不存在,返回a.end(),這裏需要注意的是,a.end()不在查找範圍內。

7.輸出id之類有7位數字的數字串時,注意使用佔位符

如:
printf("%07d")
%04d 表示在輸出一個小於4位的數值時, 將在前面補0使其總寬度
爲4位。

8.atoi() 將字符串轉換爲整數形

atoi(array to integer)返回類型爲int型,用法例如:

int t= atoi(s);

9.const char 和string的轉換與區別

  • const char* 不可修改,一般用作常量字符串
  • string類型讀值進入時可以考慮使用**c_str()**轉換成固定的值
//1. string轉const char*
const char* c_s = s.c_str();

//2. const char*轉string 直接賦值即可
const char* c_s ="abc";
string s(c_s);

&,*的含義與區別:

在c++中,當申明變量int *p 的時,表示p是一個儲存地址的變量;p指向地址爲00000000的地址單元。
當申明指針p之後,再用 *p表示p指向的內容;&表示取變量的地址

    int a=123;
    //&a表示a在內存中的地址
    cout<<"a: "<<a<<endl<<"a's address:"<<&a<<endl;
    //此時p是一個指針,指向a所在的位置
    int *p=&a;
    cout<<"p: "<<p<<endl;
    //聲明p之後,在p之前添加*表示p指向內存的值
    cout<<"p's value: "<<*p<<endl;
    //同時p也是 一個變量,在內存中也有一個地址儲存它,但其地址不是a的地址
    cout<<"p's address: "<<&p<<endl;
   
.,->的含義與區別:
  • A.B : A爲對象或者結構體;如struct node p,訪問爲p.a

  • A->B: A只能是指向類、結構、聯合的指針;node * p,訪問必須爲p->a

class A
{ int a ;
};
int main()
{
	A b;
	A *p = &b;
	b.a; //類的對象訪問
	p->a; //類的指針訪問
}

技巧篇:

1.當發生段錯誤時,可以很快鎖定對應問題區域

在這裏插入圖片描述

  • 對函數的傳參,一定要用引用,或者索引,例如dfs中,不然容易超時。

2.運行超時時:

可以考慮把循環裏的初始化或者判定條件移到外面只定義一遍:
如:a.length() set ::iterator it;

	可以減少運行時間的正確操作:
	set<int> ::iterator it;
    for(it=student[temp].begin();it!=student[temp].end();it++)
         printf(" %d", *it);
	
	int lens1 = strlen(s1), lens2 = strlen(s2);
    bool flag[256] = {false};
    for(int i = 0; i < lens2; i++)
        flag[s2[i]] = true;
    for(int i = 0; i < lens1; i++) {
        if(!flag[s1[i]])
            printf("%c", s1[i]);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章