C++ 語法筆記

目錄

清單


cin

cin.get()

接收單字元,會接受空格、\n,用if判斷停止點
用法:
1.

char a;
cin.get(a);
char a[10];
cin.get(a, 10);
※實際上會接收0~8字元 
a[9] == '\0' //自動添加
僅忽略掉1個輸入字元
cin.get();

cin.getline()

接收字串,用char[]接收
同cin.get(),但可新增遇某字元自動為止功能

cin.getline(接收對象, 接收個數, 遇某字元則停)
接收個數一樣為n-1,最後一位會被寫入'\0'
最後字元若未填預設為'\0'

e.g.

char a[5] = {'z', 'z', 'z', 'z', 'z'};
cin.getline(a, 4, '3');
for (int i = 0; i < 5; i++){
    cout << a[i] << ',';
}
//1,2,,z,z,

若先遇到某字元,則前面照常寫入,該字元改為'\0'寫入位置
反之,個數先滿則停,且第n個同樣被寫成'\0'

getline()

來源流(cin、stream),用string接收,但可以接收換行(需要配合截斷字元)

將cin用getline寫進string

string str;
getline(cin, str, '截斷字元');//str接收後不包含被截斷字
//若無給予截斷字元參數,預設為直到\n停止,反之截斷前所有\n都會被吃進去

若輸入字串在getline();被截斷
截斷後的值下一位開始依然存在stream
若再使用getline後續會被取出

e.g.

string str;
getline(cin, str, 'A');
cout << str << endl;
getline(cin, str, 'B');
cout << str << endl;
getline(cin, str);
cout << str << endl;

只輸入:"This_is_an_Apple,not_a_Banana."
產生三行輸出:
This_is_an

pple,not_a
anana.

接收不定量的數值,中間會用","隔開

vector <int> numbers;
string in_str;

while (getline(cin, in_str) {//相當於抓cin換行前的所有內容
    if (in_str == "\0") {//如果enter輸入值是空的
        break; //推入陣列直接結束程式,防報錯
    }          //測資有限制可不加
}       
stringstream str_stream(in_str);//把in_str寫入過渡用sstream
string text;
while (getline(str_stream, text, ',')) {
    numbers.pushback(stoi(item));
}  //因為截斷字元不保留,剩餘內容保留特性
   //以','為切點被切割的數字都會被推進vec,最後為'\n'照樣會截斷捨去

cout

控制整體輸出小數位

控制小數位數,並自動四捨五入

#include <iomanip>
//輸出到小數點後第n位
cout << fixed << setprecision(3) << 3.14159;	
//3.141

使用後會影響整個檔案的cout

取消後續cout影響

cout << defaultfloat;

將對fixed的影響清除(小數),但setprecision(位數)狀態依然保持
僅能再使用setprecision() 重新覆蓋定義
以上對int不影響

三大處理(int, string, char)

轉換

  • 字元轉int

    ​​​​char a;
    ​​​​a - '0' = //實際數值
    
    • string導到現有char[]
      可取片段string來源,可接上或覆蓋部分char片段
      ​​​​string str = "ABChello";
      ​​​​char p[10] = {};
      ​​​​str.copy(p + 2, 5, 3); //str複製到p,複製str[3]開始5個字元
      ​​​​                      //(到str[7]),到p[2]開始(略過p[0],p[1])
      
  • int跟string互轉(stream)

#include <sstream>
//s1為過渡媒介
stringstream s1;
s1.str("");
s1.clear();

1. int轉string
    int num;
    string op;
    s1 << num;
    s1 >> op

2. string轉int
    int op_num;
    string ip_str;
    s1 << ip_str;
    s1 >> op_num;
  • int跟string互轉(to_string, stoi)
    a可以是int、double等float

    數值轉字串

    ​​  to_string(a);
    

    將數字的字串轉成int

    ​​  a = "1024";
    ​​  int num = stoi(a);
    

注意stoi處理時會自動把"前面"的空格省略,並往後取到非數值前

e.g.
輸入:" 23a"
->stoi取得值 : 23
輸入 : " 90 12a"
->stoi取得值 : 90
//注意,第一個'-'會當成負號讀入,往後的負號會忽略
輸入 : " -23-4a"
->stoi取得值 : -23

int主體

  • int拆分
    字串拆分重組數字

    ​​​​num = num * 10 + (a - '0');
    

    e.g.

    ​​​​num = 120;
    ​​​​1 * 10 + (a – '0') = 12 //*10左移效果+個位數 達成拆分合體
    

string主體

  • 子函數大全

    • append() - 接上字串

      1. 把str1內容接到str2後

        str1.append(str2);

      2. 接上片段

        str2.append(str1, 開始位, [數量])

      3. 接上指定字串//限已知字串

        str2.append("Text", [從頭開始數量])

        亦可用3參數,注意2參數判定不同
      4. 接上指定數量字元

        str2.append(數量, '字元')

    • assign() - 賦予字串在str.end()

      1. 複製

        str2.assign(str1);

        使得str2 == str1

      2. 複製片段

        str2.assign(str1, 開始位, [複製數量])

      3. 賦予指定字串//限已知字串

        str2.assign("Text", [從頭開始數量])

        亦可用3參數,注意2參數判定不同

      4. 賦予指定數量字元

        str2.assign(數量, '字元')

    • replace() - 取代子字串

      1. ordinary
        將1~2參數範圍取代成str2

        str1.replace(str1開始位, 選取數量, str2);

      2. 找出指定位置後取代

        str1.replace(str1.find("text"), 選取數量, 字串);

        find結果的begin~選取量,取代為指定字串

    • insert() - 插入字串

      str1.insert(開始位, 字串)

    • erase() - 清除部分內容

      str1.erase(開始位, 清除量)

    • size() - 字串目前大小

      str1.size()

    • find() - 尋找字串

      善用未找到時 == string::npos

      1. 以是否存在取bool
      ​​if (str1.find(str2) != string::npos) {//在str1有找到str2
      ​​	//...
      ​​}
      ​​else {
      ​​	//...
      ​​}
      
      1. 找出指定字元或串在第幾個位置

        注意回傳值是查詢值第一位對應

        ​​​​​​​​​​​​int pos;
        ​​​​​​​​​​​​pos = str1.find(str2);
        
      2. 從頭開始找出字串中任何一個字元就回傳位置

        ​​​​​​​​​​​​int pos;
        ​​​​​​​​​​​​pos = str1.find_first_of(str2);
        

        取反:從頭找任何一個不包含的字元位置

        ​​​​​​​​​​​​pos = str1.find_first_not_of(str2);
        
      3. 從尾開始找出字串中任何一個字元就回傳位置

        ​​​​​​​​​​​​pos = str1.find_last_of(str2);
        

        取反:從尾找任何一個不包含的字元位置

        ​​​​​​​​​​​​pos = str1.find_last_not_of(str2);
        
    • swap() - 普通交換兩字串

      ​​​​​​​​str1.swap(str2);//兩者內容互換
      
    • substr() - 取得字串中部分內容

      ​​​​​​​​string temp;
      ​​​​​​​​temp = str1.substr(開始位, 數量)
      ​​​​​​​​//數量寫超過下標時,只取到下標為止不報錯
      
    • empty() - 偵測是否為空回傳bool

      ​​​​​​​​bool isEmpty;
      ​​​​​​​​isEmpty = str1.empty();
      
    • erase-remove - 清除字串中所有特定字元

      ​​​​​​​​str.erase(remove(str.begin(), str.end(), 'T'), str.end());
      
  • char主體

    • cctype - 字元判斷與轉換
      ​​​​​​​​#include <cctype>
      
      • 判斷
        以bool存取
        • isupper():判斷字元是否為大寫字母
        • islower():判斷字元是否為小寫字母
        • isalpha():判斷字元是否為字母
        • isdigit():判斷字元是否為純數字
        • isalnum():判斷字元是否為數字或大小字母轉換
      • 轉換
        • toupper():字元轉大寫
        • tolower():字元轉小寫

      char[]以index計數
      注意寫int[]、char[]時的index計數器關係
      最後index數值會 = size


陣列

將一維陣列清空/寫值

int arr[];
fill(arr, arr + size, 0);

清除二維陣列

int num[100][100];
memset(num, 0, sizeof(num));
//限定為0,否則只能用雙重for 或 for + fill

vector主體

#include<vector>
  • 預宣告空間初始化
    ​​​​vector<int> num(10, 0); //初始化產生num[0~9],數值為0
    
  • 標準遍歷式
    ​​​​vector<int> num;
    ​​​​for (auto it = num.begin(); it != num.end(); it++) {
    ​​​​    cout << *it << endl;
    ​​​​}
    
  • 取遍歷值
    ​​​​vector<int> num;
    ​​​​for (auto i : num) {
    ​​​​    cout << i << endl;//i為遍歷num的值
    ​​​​}
    
  • Sort
    ​​​​vector<int> v;
    
    • 升序
      ​​sort(v.begin(), v.end());
      
    • 降序(利用r反向)
      ​​​​​​​​sort(v.rbegin(), v.rend());
      
  • 翻轉應用
    ​​​​vector<int> v;
    ​​​​reverse(v.begin(), v.end());
    

    一維陣列 a1, n 互換 a1 + 1, n - 1互換
    二維陣列 只換i(直行)不換j(橫列)

  • 查值系列 & iter轉idx
    ​​​​vector<int> v;
    ​​​​auto iter = find(v.begin(), v.end(), 10);
    ​​​​if (iter != v.end()) {
    ​​​​    int idx = iter - v.begin();
    ​​​​    cout << idx;
    ​​​​}
    ​​​​else {
    ​​​​    cout << "v沒有10";
    ​​​​}
    
  • 兩組vector<int>對應位置合併相加
    ​​​​vector<int> v1, v2;
    ​​​​int max_size = max(v1.size(), v2.size());
    ​​​​v1.resize(max_size);
    ​​​​v2.resize(max_size);
    ​​​​vector<int> result(max_size);
    
    ​​​​transform(v1.begin(), v1.end(), v2.begin(), result.begin(), plus<int>());
    ​​​​//result每位將被寫入對應的位數相加
    
  • 拼接兩vector
    ​​​​vector<int> v1, v2;//其他型別無異
    ​​​​v1.insert(v1.end(), v2.begin(), v2.end());
    
  • 排序後刪除重複值
    ​vector<int> v = { 1, 2, 4, 3, 5, 2 };
    ​sort(v.begin(), v.end());//先排序
    ​//unique(iter.begin(), iter.end()) 把相鄰重複值扔到back
    ​//erase 移除指定範圍(iter.begin(), iter.end())
    ​v.erase(unique(v.begin(), v.end()), v.end());
    ​//因為unique會回傳排好後+1的位置,等於要移除範圍的begin
    
  • 二維串列(vector)使用
    ​​​​vector<int> a[10];
    
    a產生10個 i (0~9),利用pushback增加 j
    利用a[i][j]格式取值
    ​a[4].pushback(1); //a[4][0] == 1
    ​a[4].pushback(2); //a[4][1] == 2
    ​a[3].pushback(3); //a[3][0] == 3
    

queue

一邊檢索,一邊增加預備檢索序列

#include <queue>
queue<int> q;
  • q.push():推入尾值
  • q.pop():移除首值
  • q.back():取得尾值
  • q.front():取得首值
  • q.size():回傳q目前長度
  • q.empty():回傳q是否為空

set

#include <set>

set會自動去除重複元素以及排序

set<int> a_set{ 1, 3, 2 };//成為1 2 3
set<int, greater<int> > a_set{ 1,3,2 };//降序(3 2 1)
  • a_set.insert():插入元素
  • a_set.erase():清除某個元素
  • a_set.clear():清空a_set
  • a_set.empty():判斷a_set是否為空
  • a_set.size():取得a_set目前大小

移動iter指向

auto it = a_set.lower_bound(1);//it指到第一個 >= 1的位置
auto it = a_set.upper_bound(1);//it指到第一個 >  1的位置

清除指定元素,並記錄是否有進行清除動作

bool is_erased = a_set.erase(2);
if (is_erased) {
    cout << "成功清除 2" << endl;
}
else {
    cout << "不存在 2" << endl;
}

尋找某值是否存在

if (a_set.find(1) == a_set.end()) {
    cout << "不存在1" << endl;
}
else {
    cout << "找到1" << endl;
}

deque

頭尾都能增加元素的雙向佇列
在中間插入元素的效率較高
但占用記憶體空間較vector多
隨機插入效率高(insert、erase)
隨機訪問效率低(find、dq[index])

隨機訪問頻率較高選擇vector
頭尾兩端都需要添加元素選擇deque

#include <deque>
deque<int> dq; 
deque<int>::iterator it;

dq.push_back():推入尾值
dq.pop_back():移除尾值
dq.push_front():推入首值
dq.pop_front():移除首值
dq.insert(iter, 1):在iter的位置插入1
dq.erase(iter):
dq.clear():
dq.empty():
dq.size():

map

寫入key跟value後,會依照初始宣告自動排列
map中key不會重複,呼叫時即以key當作陣列的index使用
架構: //key跟value分別填入資料型別

  1. 升序排列
    map<key, value> a_map;
  2. 降序排列
    map<key, value, greater<key> > a_map; //注意隔開> >
    map<char, int, greater<char> > a_map;
    //insert不要在比賽使用,判斷型別複雜
    a_map['a'] = 93;
    a_map['b'] = 24;
    a_map['c'] = 10;
    cout << a_map['a'] << endl;//輸出93
    cout << a_map['T'] << endl;
    //注意! T不存在,執行後會輸出0,
    //且map紀錄一筆'T', 0,在遍歷時會被掃到
    a_map.erase('a');
    for (auto s: a_map) {
    //first取出key,second取出value
    cout << s.first << ", " << s.second << endl;
    //分別輸出b, c, T
    }
    a_map.clear();
    a_map.empty();
    a_map.size();

map實際應用:
處理來源非連續數字,且最終不需輸出原本名稱(反之要用struct)
int getID(string p) {//將物件名稱寫入item取得ID
if (node.find§ == node.end()) {//沒找到key = p的item
node[p] = node.size();
}
return node[p];
}

求極值

#include <algorithm>
注意要用 *min / max_element
求max
1.vector
int maxValue = *max_element(v.begin(), v.end());
2.一般陣列
int maxValue = *max_element(num, num + 5);//(size = 5)
求min
1.vector
int minValue = *min_element(v.begin(), v.end());
2.一般陣列
int minValue = *min_element(num, num + 5);//(size = 5)

求極值位置

注意求位置用一般max / min_element
#include<algorithm>

求max
1.vector
int maxPos = max_element(v.begin(), v.end()) - v.begin();
2.一般陣列
int maxPos = max_element(num, num + 5) - num;//(size = 5)
求min
1.vector
int minPos = min_element(v.begin(), v.end()) - v.begin();
2.一般陣列
int minPos = min_element(num, num + 5) - num;//(size = 5)

已知寬度二維陣列讓外部函式修改

//用於需要在外部改值,不傳回。在void的變更會直接改變main的num值
void A(int **num, int i_size, int j_size) {
//code 正常用Num[i][j]存取相同位置
}
int main() {
int num[][5];
int p[3] = { num[0], num[1], num[2] };//複製一份傳遞用
//此處
p[3]決定i長度 //取i,注意順序有差
int i_size = 3;
A(p, i_size, 5);
}

找最大連續子數列

int GetMax(vector<int> num, int size) {
int now = 0, max_n;
max_n = num[0];
for (int i = 0; i < size; i++) {
now += num[i];
if (now > max_n) {
max_n = now;
}
else if (now < 0) {
now = 0;
}
}
return max_n;
}//建議用於結果會 >= 0,全負數依然會報長度0,需依題意調整

Keyword

const

常數,賦予不可變更的特性

  • const 變數
    ​​​​const int n = 5;
    ​​​​n = 10; // compile error
    

    將int n 設為唯讀,不允許assignment,會報錯

英文名詞定義

  • assignment

    賦值的操作,即 =


tags: C++
Select a repo