# 常用容器 container

# Vector

簡單的講就是動態的陣列,大小可以是 0 到無限大

  1. 標頭檔:<vector>
  2. v [i]:v 的第 i 項
  3. v.size ():回傳 v 目前的長度
  4. v.push_back (T a):在 v 的結尾加一個 a
  5. v.pop_back ():刪除 v 的最末項,若 v 為空,會發生無法預期的結果
  6. v.empty ():回傳一個 bool,表示 v 是否為空的
  7. v.clear ():清空 v,但原本的空間不會被釋放掉。

# 範例 1

#include<iostream>
#include<vector>
using namespace std;
vector <int> v;
int main(){
    v.push_back(10);  //[10]
    v.push_back(20);  //[10 , 20]
    v.push_back(30);  //[10 , 20 , 30]
    int length = v.size();
    for(int i = 0; i < length;i++)
        cout << v[i] << " "; //10 20 30
}

# 範例 2

#include<iostream>
#include<vector>
using namespace std;
vector <int> v;
int main(){
    v.push_back(10);  //[10]
    v.push_back(20);  //[10 , 20]
    v.pop_back();     //[10]
    v.push_back(30);  //[10 , 30]
    int length = v.size();  // = 2
    for(int i = 0; i < length;i++)
        cout << v[i] << " "; //10 20 30
}

另外,vector 也可以像是 array 一樣,(預) 開設一個固定的大小,用 v () 來控制

# 範例 3

#include<iostream>
#include<vector>
using namespace std;
vector <int> v(5);  // int v[5]={ };
int main(){
    int length = v.size();  // length = 5
    for(int i = 0;i<length;i++)
        v[i] = i * 10;   // [ 0 , 10 , 20 , 30 , 40 ]
    for(int i = 0;i<length;i++)
        cout<<v[i]<<" "; // 0 10 20 30 40
}

# deque

  1. 位於 <deque> 標頭檔。
  2. 可視為可以在最前面加東西刪東西的 vector。
  3. d.pop_front (): 刪掉最前面的東西
  4. d.push_front (a): 在最前面加東西
  5. d.pop_back (): 刪掉最後面的東西
  6. d.push_back (a): 在最後面加東西
  7. 時間和空間複雜度很爛,沒事不要用 deque。

# Stack

Stack 就像是疊盤子,最先放置的會壓在最下面,最先放的會先拿出,有 First in,Last out 的特性

  1. 標頭檔:<stack>
  2. st.push (): 疊上一個盤子
  3. st.pop (): 把最上方的盤子移除掉
  4. st.top (): 取得最上面的值
  5. st.size (): 目前的盤子數
  6. st.empty (): 當沒有值的時候會 true

# 範例 1

#include<iostream>
#include<stack>
using namespace std;
stack <int> st;
int main(){
    st.push(10);  //| 30 |
    st.push(20);  //| 20 |
    st.push(30);  //|_10_|
    while(!st.empty()){
        cout<<st.top()<<" "; // 30 20 10
        st.pop();
    }
}

# Queue

Queue 就像是排隊買東西,從尾巴進,前頭出來,有 First in,First out 的特性

  1. 標頭檔:<queue>
  2. q.push (): 把一個值加到尾巴
  3. q.pop (): 把第一個值移除掉
  4. q.back (): 得到尾巴的值
  5. q.front (): 得到頭的值
  6. q.empty (): 當 queue 沒有值的時候會 true
#include<iostream>
#include<queue>
using namespace std;
queue <int> q;
int main(){
    for(int i = 0;i<5;i++)
        q.push(i*10);  //[0 , 10 , 20 , 30 , 40]
    while(!q.empty()){
        cout<<q.front()<<" ";
        q.pop();
    }
}

# priority_queue

priority_queue,就是 queue 的變種,內建了函式實現 binary heap 結構,可以維持最頂的元素永遠是最大 (最小) 的

  1. 標頭檔: <queue>
  2. pq.push (a): 將 a 加入 pq 內部
  3. pq.pop (): 將 pq 中最大 (最小) 的元素移除
  4. pq.top (): 回傳 pq 中最大 (最小) 的元素
  5. pq.empty (): 判斷還有沒有值在裡面

# 範例 1

#include<iostream>
#include<queue>
using namespace std;
priority_queue <int> pq; // 由大到小排列 (最大優先)
// priority_queue<int,vector<int>,less<int> >pq;
int main(){
    pq.push(30); //[30]
    pq.push(50); //[50 , 30]
    pq.push(20); //[50 , 30 , 20]
    pq.push(80); //[80 , 50 , 30 , 20]
    pq.pop();    //[50 , 30 , 20]
    while(!pq.empty()){
        cout<<pq.top()<<" "; // 50 30 20
        pq.pop();
    }
}

# 範例 2

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >pq;// 由小到大排列 (最小優先)
int main(){
    pq.push(30); //[30]
    pq.push(50); //[30 , 50]
    pq.push(20); //[20 , 30 , 50]
    pq.push(80); //[20 , 30 , 50 , 80]
    pq.pop();    //[30 , 50 , 80]
    while(!pq.empty()){
        cout<<pq.top()<<" "; // 30 50 80
        pq.pop();
    }
}

# Map

Map 就像是一個對應表,也就像是 Python 的字典

  1. 標頭檔:<map>
  2. mp []: 得到對應的值
  3. mp.count (): 檢查某個值是否有對應值

# 範例 1

#include<iostream>
#include<map>
using namespace std;
map <string,int> mp;  // string -> int
int main(){
    mp["one"] = 1;
    mp["two"] = 2;
    cout<<mp.count("one")<<endl;   //--> 1 (有對應)
    cout<<mp.count("two")<<endl;   //--> 1 (有對應)
    cout<<mp.count("ten")<<endl;   //--> 0 (無對應)
}

# 範例 2

#include<iostream>
#include<map>
using namespace std;
map <string,int> mp;  // string -> int
int main(){
    mp["one"] = 1;
    mp["two"] = 2;
    mp["three"] = 3;
    cout<<mp["two"]<<endl;   // -->2
    cout<<mp["ten"]<<endl;   // -->0
}

# Set

顧名思義,就只是個集合

  1. 標頭檔:<set>
  2. s.insert (): 把一個數字放進集合
  3. s.erase (): 把某個數字從集合中移除
  4. s.count (): 檢查某個數是否有在集合中

# 範例 1

#include<iostream>
#include <set>
using namespace std;
set <int> s;
int main(){
    s.insert(20);   // s = {20}
    s.insert(10);   // s = {10, 20}
    s.insert(30);   // s = {10, 20, 30}
    cout << s.count(20) << endl;    // 存在 -> 1
    cout << s.count(100) << endl;   // 不存在 -> 0
    s.erase(20);     // s = {10, 30}
    cout << s.count(20) << endl;    // 0
}

# multiset,multimap

在 <set>,<map> 中分別有 multiset 和 multimap,與前面的差不多,唯一的差別在於 multiset 和 multimap 中鍵值可以重複出現

# 疊代器 iterator

叠代器提供對一個容器中的對象的訪問方法。叠代器就如同一個指針,叠代器是一種檢查容器內元素並遍歷元素的數據類型。
標準庫為每一種標準容器(包括 vector)定義了一種叠代器類型。

# iterator 類型

每個標準庫容器類型都定義了一個名為 iterator 的成員,用來定義自己的叠代器。如:

vector<int>::iterator iter;
stack<int>::iterator iter;

# begin 和 end 操作

每種容器都定義了一對命名為 begin 和 end 的函數,用於返回叠代器。如果容器中有元素的話,由 begin 返回的叠代器指向第一個元素:

vector<int>::iterator iter = v.begin();

把 iter 初始化為由名為 vector 操作返回的值。假設 vector 不空,初始化後,iter 即指該元素為 v [0]。

vector<int>::iterator iter2 = v.end()

由 end 操作返回的叠代器指向 vector 的末端元素的下一個,被稱為超出末端叠代器。

# 叠代器支持的其他方法

比較:用 == 或!= 操作符來比較兩個叠代器,如果兩個叠代器對象指向同一個元素,則它們相等,否則就不相等。
使用叠代器遍歷容器:

vector<int>::iterator iter = v.begin()
for (; iter != v.end(); ++iter)
    cout<<*iter<<endl;
//-------------------------------------------------
for (int i = 0;i < v.size();i++)
    cout<<v[i]<<endl;

# 叠代器的算術操作

除了一次移動叠代器的一個元素的增量操作符外,vector 叠代器也支持其他的算術操作。包括:

iter + n
iter - n
iter1 - iter2
vector<int>::iterator mid = v.begin() + v.size() / 2;
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay