C++ STL 速查表



這份 C++ STL 速查表涵蓋了從基本的 STL(例如 向量雜湊對映、集合等)到高階概念(例如函式物件迭代器等)的廣泛主題。它專為希望快速閱讀關鍵概念以及語法和相關示例的程式設計師而設計。

介紹

標準模板庫 (STL) 是一個 C++ 庫,包含所有 函式 模板。它用於實現基本的資料結構(例如 雜湊集列表等)和函式(例如數學、演算法等),幷包含 C++ 程式語言中所有可用的容器

STL 的組成部分

標準模板庫包含多個容器和函式,可以按以下方式分類:

STL 容器

STL 容器模板類包含諸如動態陣列(或向量、列表)、雜湊對映、雜湊集、連結串列等資料結構。這些用於儲存和對資料執行操作。

容器模板具有以下組成部分:

  • 順序容器
  • 容器介面卡
  • 關聯容器
  • 無序容器

每個容器都有其各自的標頭檔案,可以在程式開始時包含。例如,std::vector 包含在 #include<vector> 庫中。

順序容器

順序容器實現具有順序訪問的資料結構。這些包括:

容器介面卡

容器介面卡透過為順序容器提供不同的介面來實現佇列、堆疊等資料結構。這些包括:

關聯容器

關聯容器用於儲存有序資料,可以使用其鍵值快速搜尋。這些包括:

無序容器

無序容器類似於關聯容器,但唯一的區別是它們不儲存排序資料。儘管如此,這些容器仍使用鍵值對提供快速的搜尋時間。它們是:

現在我們已經建立了所有容器的學習圖,我們將簡要解釋 STL 中每個容器以及示例程式碼:

STL 中的向量

向量在執行時初始化為動態陣列,其大小是可變的。它可以在 C++ <vector> 標頭檔案中找到。

語法

vector<data_type> vec1; //1D vector
vector<vector<data_type>> vec2; //2D vector
vector<container_type<data_type>> vec3; //2D vector of other container
vector<data_type> vec1(n); //vector of size n
vector<data_type> vec1(n,k); // vector of size n, with each element=k

向量模板中有多個函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向最後一個元素之後理論元素的迭代器。 O(1)
3. size() 返回存在的元素數量。 O(1)
4. empty() 如果向量為空,則返回 true,否則返回 false。 O(1)
5. at() 返回特定位置的元素。 O(1)
6. assign() 為向量元素分配新值。 O(n)
7. push_back() 在向量末尾新增一個元素。 O(1)
8. pop_back() 從末尾移除一個元素。 O(1)
9. insert() 在指定位置插入一個元素。 O(n)
10. erase() 刪除指定位置或範圍內的元素。 O(n)
11. clear() 移除所有元素。 O(n)

此處,時間複雜度表示向量模板的不同成員函式的時間複雜度。有關時間複雜度的更多資訊,請訪問本文:時間複雜度

示例

// C++ program to illustrate the vector container
#include <iostream>
#include <vector>
using namespace std;

int main(){
   int n=2;
   vector<int> vec1 = { 1, 2, 3, 4, 5 };
   vector<int> vec2(n,0);

   vector<vector<int>> vec3(n,vector<int>(2*n,1));

   vec1.push_back(6);

   cout << "vec1: ";
   for (int i = 0; i < vec1.size(); i++) {
      cout << vec1[i] << " ";
   }
   cout << endl<<"vec2: ";
   for (int i = 0; i < vec2.size(); i++) {
      cout << vec2[i] << " ";
   }
   cout << endl;

   vec1.erase(vec1.begin() + 4);

   cout << "vec1 after erasing: ";
   for (auto i = vec1.begin(); i != vec1.end(); i++) {
      cout << *i << " ";
   }
   cout << endl;

   cout << "vec3:-" << endl;
   for (auto i : vec3) {
      for (auto j : i) {
         cout << j << " ";
      }
      cout << endl;
   }
   cout << endl;

   vector<pair<int,int>> vec4;
   vec4.push_back({2,3});
   vec4.push_back({4,3});

   cout<<"vector of pairs, vec4 : "<<endl;
   for(auto i: vec4){
      cout<<i.first<<" "<<i.second<<endl;
   }
   return 0;
}
輸出
vec1: 1 2 3 4 5 6 
vec2: 0 0 
vec1 after erasing: 1 2 3 4 6 
vec3:-
1 1 1 1 
1 1 1 1 

vector of pairs, vec4 : 
2 3
4 3

STL 中的列表

列表容器初始化為雙向連結串列,而對於實現單向連結串列,我們使用前向列表。它可以在 C++ <list> 標頭檔案中找到。

語法

list<data_type> list1;

列表模板中有多個函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向最後一個元素之後理論元素的迭代器。 O(1)
3. size() 返回列表中元素的數量。 O(1)
4. push_back() 在列表末尾新增一個元素。 O(1)
5. pop_back() 從末尾移除一個元素。 O(1)
6. push_front() 在列表開頭新增一個元素。 O(1)
7. pop_front() 從開頭移除一個元素。 O(1)
8. insert() 在指定位置插入一個元素。 O(n)
9. erase() 刪除給定位置的元素。 O(n)
10. remove() 從列表中移除給定元素的所有副本。 O(n)

示例

#include <iostream>
#include <list>
#include <vector>
using namespace std;

int main(){
   list<int> list1 = { 1, 5, 9, 1, 4, 6 };

   cout << "List1 first and last element: " << list1.front() <<" "<<list1.back()<<endl;

   // adding element
   list1.insert(list1.begin(), 5);

   // deleting element
   list1.erase(list1.begin());

   // traversing list1
   cout << "list1: ";
   for (auto i = list1.begin(); i != list1.end(); i++) {
      cout << *i << " ";
   }
   cout << endl;

   return 0;
}
輸出
List1 first and last element: 1 6
list1: 1 5 9 1 4 6 

STL 中的雙端佇列

雙端佇列容器初始化為雙端佇列,可以在佇列的兩端推送和彈出元素。它可以在 C++ <deque> 標頭檔案中找到。

語法

deque<data_type> dq1;

雙端佇列模板中有多個函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向最後一個元素之後理論元素的迭代器。 O(1)
3. at() 訪問指定元素。 O(1)
4. [ ] 訪問給定索引處的元素。 O(1)
5. front() 返回第一個元素。 O(1)
6. back() 返回最後一個元素。 O(1)
7. size() 返回元素的數量。 O(1)
8. push_back() 在末尾新增元素。 O(1)
9. pop_back() 從末尾移除元素。 O(1)
10. push_front() 在開頭新增元素。 O(1)
11. pop_front() 從開頭移除元素。 O(1)

示例

#include <deque>
#include <iostream>
using namespace std;

int main(){

   deque<int> dq = { 1, 2, 3, 4, 5 ,6, 8 };
   cout<<"Initial Deque: "<<endl;
   for (auto i : dq) {
      cout << i << " ";
   }
   cout<<endl;
   dq.push_front(dq.back());
   dq.pop_back();
   for (auto i : dq) {
      cout << i << " ";
   }
   cout<<endl;

   dq.push_front(dq.back());
   dq.pop_back();
   for (auto i : dq) {
      cout << i << " ";
   }
   cout<<endl;

   dq.pop_back();
   dq.pop_front();
   for (auto i : dq) {
      cout << i << " ";
   }
   cout<<endl;

   dq.push_front(11);
   dq.push_back(99);

   for (auto i : dq) {
      cout << i << " ";
   }

   return 0;
}
輸出
Initial Deque: 
1 2 3 4 5 6 8 
8 1 2 3 4 5 6 
6 8 1 2 3 4 5 
8 1 2 3 4 
11 8 1 2 3 4 99 

STL 中的堆疊

堆疊容器初始化為後進先出 (LIFO) 容器,可以在頂部推送元素,並從頂部彈出元素。因此,最後一個進入的元素是第一個從容器中退出的元素。它可以在 C++ <stack> 標頭檔案中找到。

語法

stack<data_type> s1;

堆疊模板中有多個函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. empty() 如果堆疊為空,則返回 true,否則返回 false。 O(1)
2. size() 返回堆疊中元素的數量。 O(1)
3. top() 返回頂部元素。 O(1)
4. push(x) 將一個元素壓入棧中。 O(1)
5. pop() 從棧中移除一個元素。 O(1)

示例

// C++ Program to illustrate the stack
#include <bits/stdc++.h>
using namespace std;

int main(){
   stack<int> s;

   s.push(2);
   s.push(9);
   s.push(3);
   s.push(1);
   s.push(6);

   cout << "Top is: " << s.top() << endl;

   while (!s.empty()) {
      cout<<"size is: "<<s.size()<<" ";
      cout << "element is: "<<s.top() << endl;
      s.pop();
   }
   return 0;
}
輸出
Top is: 6
size is: 5 element is: 6
size is: 4 element is: 1
size is: 3 element is: 3
size is: 2 element is: 9
size is: 1 element is: 2

STL中的佇列

佇列容器初始化為一個先進先出(FIFO)容器,元素可以從隊尾壓入,從隊首彈出。因此,第一個進入的元素也是第一個離開容器的元素。它可以在C++的``標頭檔案中找到。

語法

queue<data_type> q1;

佇列模板中,有不同的函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. empty() 如果佇列為空,則返回true;否則返回false。 O(1)
2. size() 返回佇列中專案的數量。 O(1)
3. front() 返回隊首元素。 O(1)
4. back() 返回隊尾元素。 O(1)
5. push() 向佇列中新增一個專案。 O(1)
6. pop() 從佇列中移除一個專案。 O(1)

示例

#include <iostream>
#include <queue>
using namespace std;

int main(){
   queue<int> q;
   q.push(1);
   q.push(1);
   q.push(6);
   q.push(1);

   cout << "Front element: " << q.front() << endl;
   cout << "Back element: " << q.back() << endl;

   cout << "q: ";
   int size = q.size();

   for (int i = 0; i < size; i++) {
      cout << q.front() << " ";
      q.pop();
   }

   return 0;
}
輸出
Front element: 1
Back element: 1
q: 1 1 6 1 

STL中的雜湊集合/集合

集合容器初始化為唯一元素儲存的資料結構,它也實現了排序(升序和降序)。它通常使用紅黑樹作為底層資料結構。它可以在C++的``標頭檔案中找到。

語法

set<data_type> set;
set<data_type, greater<data_type>> set2; //this is a set in descending order
set<data_type, comparator/lambda_function> set3; //this is a set in custom order

集合模板中,有不同的函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向最後一個元素的迭代器。 O(1)
3. size() 返回元素的數量。 O(1)
4. empty() 檢查容器是否為空。 O(1)
5. insert() 插入單個元素。 O(logn)
6. erase() 移除給定的元素。 O(logn)
7. clear() 移除所有元素。 O(n)
8. find() 如果存在給定的元素,則返回指向該元素的指標;否則,返回指向末尾的指標。 O(logn)

示例

#include <iostream>
#include <set>
#include <vector>
using namespace std;

int main(){
   set<int> set;
   set.insert(9);
   set.insert(11);
   set.insert(9);
   set.insert(11);

   bool flag=set.find(9)!=set.end();

   cout<<"Is there a 9 in the set? "<<flag<<endl;

   set.insert(21);

   for (auto i : set) {
      cout << i << " ";
   }
   cout << endl;
   return 0;
}
輸出
Is there a 9 in the set? 1
9 11 21

STL中的雜湊對映/對映

對映是一個容器,它以鍵值對的形式儲存資料,並按鍵的升序排序,每個鍵都是唯一的。它使用紅黑樹資料結構實現。它包含在``標頭檔案中。

語法

map<key_type,value_type> map;

對映模板中,有不同的函式。這些函式在下面的表格中簡要解釋:

序號 函式 函式說明 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向理論上最後一個元素之後元素的迭代器。 O(1)
3. size() 返回對映中元素的數量。 O(1)
4. insert() 向對映中新增一個新元素。 O(logn)
5. erase(iterator) 移除迭代器指向位置處的元素。 O(logn)
6. erase(key) 從對映中移除鍵及其值。 O(logn)
7. clear() 從對映中移除所有元素。 O(n)

示例

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main(){
   map<char,int> map;
   string s="abbacdbbac";
   for(char c: s){
      map[c]++;
   }

   for(auto it:map){
      cout<<it.first<<" : "<<it.second<<endl;
   }
   cout<<"after erasing element 'c' : "<<endl;
   map.erase('c');
   for(auto it:map){
      cout<<it.first<<" : "<<it.second<<endl;
   }
   return 0;
}
輸出
a : 3
b : 4
c : 2
d : 1
after erasing element 'c' : 
a : 3
b : 4
d : 1

STL中的無序集合

無序集合容器儲存唯一的資料值,但與集合的區別在於資料沒有按照任何順序儲存。它使用``標頭檔案實現。

語法

unordered_set<data_type> set;

無序集合模板中,有不同的函式。這些函式在下面的表格中簡要解釋:

序號 函式 描述 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向理論上最後一個元素之後元素的迭代器。 O(1)
3. size() 返回元素的數量。 O(1)
4. empty() 如果無序集合為空,則返回true;否則返回false。 O(1)
5. insert() 向容器中插入一個專案。 O(1)
6. erase() 從容器中移除一個元素。 O(1)
7. find() 如果存在給定的元素,則返回指向該元素的指標;否則,返回指向末尾的指標。 O(1)

示例

#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;

int main(){
   unordered_set<int> set;
   set.insert(19);
   set.insert(10);
   set.insert(13);
   set.insert(21);

   bool flag=set.find(9)!=set.end();

   cout<<"Is there a 9 in the set? "<<flag<<endl;

   set.insert(21);

   for (auto i : set) {
      cout << i << " ";
   }
   cout << endl;
   return 0;
}
輸出
Is there a 9 in the set? 0
21 13 10 19 

STL中的無序對映

在無序對映容器中,資料儲存方式與對映容器類似,但儲存資料的順序是隨機的,因此不遵循升序或降序。它包含在``標頭檔案中。

語法

unordered_map<key_type, value_type> map;

無序對映模板中,有不同的函式。這些函式在下面的表格中簡要解釋:

序號 函式 描述 時間複雜度
1. begin() 返回指向第一個元素的迭代器。 O(1)
2. end() 返回指向理論上最後一個元素之後元素的迭代器。 O(1)
3. size() 返回元素的數量。 O(1)
4. empty() 如果無序對映為空,則返回true;否則返回false。 O(1)
5. find() 如果存在給定的元素,則返回指向該元素的指標;否則,返回指向末尾的指標。 O(1)
6. bucket() 返回儲存資料的桶號。 O(1)
7. insert() 向容器中插入一個專案。 O(1)
8. erase() 從容器中移除一個元素。 O(1)

示例

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

int main(){
   unordered_map<char,int> map;
   string s="abbacdbbac";
   for(char c: s){
      map[c]++;
   }

   for(auto it:map){
      cout<<it.first<<" : "<<it.second<<endl;
   }
   cout<<"after erasing element 'c' : "<<endl;
   map.erase('c');
   for(auto it:map){
      cout<<it.first<<" : "<<it.second<<endl;
   }
   return 0;
}
輸出
d : 1
c : 2
b : 4
a : 3
after erasing element 'c' : 
d : 1
b : 4
a : 3

C++ STL中的仿函式

函式物件或仿函式是C++ STL中的物件,其行為類似於方法/函式。這些包含在``標頭檔案中。這些需要過載()圓括號運算子

C++ STL中的主要仿函式如下:

成員函式

序號 成員函式 定義
1 (建構函式) 用於構造新的std::function例項。
2 (解構函式) 用於銷燬std::function例項。
3 operator= 用於賦值新的目標。
4 swap 用於交換內容。
5 assign 用於賦值新的目標。
6 operator bool 用於檢查是否包含有效目標。
7 operator() 用於呼叫目標。

非成員函式

序號 非成員函式 定義
1 std::swap 它專門化了std::swap演算法。
2 operator== operator!= 它比較std::function與nullptr。

運算子類

序號 運算子類 定義
1 bit_and 這是一個按位與函式物件類。
2 bit_or 這是一個按位或函式物件類。
3 bit_xor 這是一個按位異或函式物件類。
3 divides 這是一個除法函式物件類。
4 equal_to 這是一個用於相等比較的函式物件類。
5 greater 這是一個用於大於不等式比較的函式物件類。
6 greater_equal 這是一個用於大於或等於比較的函式物件類。
7 less 這是一個用於小於不等式比較的函式物件類。
8 less_equal 這是一個用於小於或等於比較的函式物件類。
9 logical_and 這是一個邏輯與函式物件類。
10 logical_not 這是一個邏輯非函式物件類。
11 logical_or 這是一個邏輯或函式物件類。
12 minus 這是一個減法函式物件類。
13 modulus 這是一個取模函式物件類。
14 multiplies 這是一個乘法函式物件類。
15 negate 這是一個負函式物件類。
16 not_equal_to 這是一個用於不相等比較的函式物件類。
17 plus 這是一個加法函式物件類。

示例

#include <functional>
#include <iostream>
using namespace std;

int main(){
   equal_to<int> obj1;
   not_equal_to<int> obj2;
   greater<int> obj3;
   less<int> obj4;
   plus<int> obj5;
   minus<int> obj6;

   cout << "Functors and their usage: \n";
   cout << "Are these equal? " << obj1(11, 22) << endl;
   cout << "Are these different? " << obj2(11, 22) << endl;
   cout << "Is first index greater than second? " << obj3(10, 20) << endl;
   cout << "Is first index smaller than second? " << obj4(10, 2) << endl;
   cout << "After adding: " << obj5(10, 20) << endl;
   cout << "After subtracting: " << obj6(10, 8) << endl;

   return 0;
}

輸出

Functors and their usage: 
Are these equal? 0
Are these different? 1
Is first index greater than second? 0
Is first index smaller than second? 0
After adding: 30
After subtracting: 2

C++ STL中的演算法

在C++ STL中,演算法模板為使用者提供了各種操作,這些操作對於實現關鍵演算法至關重要,例如搜尋排序、從容器中返回最大/最小值等等。可以使用``標頭檔案訪問這些演算法。

C++中的``庫提供了許多有用的函式。下面給出一些最常用的函式:

C++中的sort()

sort()演算法用於按升序、降序或自定義順序(使用比較器lambda函式)對給定資料進行排序。

語法

sort(start_iterator,end_iterator)
sort(start,end, comparator_function) //for custom sorting

示例

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main(){
   vector<int> v = {999, 1252, 3117, 122222 , 10, 88, 2, 9, 45, 82, 546, 42, 221 , -1};
   cout<<"Ascending order: ";
   sort(v.begin(),v.end());
   for(int i:v) cout<<i<<" ";
      cout<<endl;

   cout<<"Descending order: ";
   sort(v.begin(),v.end(),greater<int>());
   for(int i:v) cout<<i<<" ";
      cout<<endl;
   return 0;
}
輸出
Ascending order: -1 2 9 10 42 45 82 88 221 546 999 1252 3117 122222 
Descending order: 122222 3117 1252 999 546 221 88 82 45 42 10 9 2 -1 

C++中的copy()

copy()演算法用於將元素從一個容器複製到另一個容器。

語法

copy(start_iterator,end_iterator, destination_operator)

示例

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main(){
   vector<int> v = { 1, 2, 3, 4, 5 , 4 ,3 , 2, 1};
   vector<int> newvec(9);
   copy(v.begin(), v.end(), newvec.begin());

   for(int &i:newvec) cout<<i<<" ";
   cout<<endl;
   return 0;
}
輸出
1 2 3 4 5 4 3 2 1 

C++中的find()

find()演算法用於在給定元素範圍內查詢關鍵元素。

語法

find (firstIterator, lastIterator, value);

示例

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main(){
   vector<int> v= { 1,3,5,2,3,1,55,41};

   // finding 5
   auto itr = find(v.begin(), v.end(), 55);
   if (itr != v.end()) {
      cout << *itr << " Element found !!!" << endl;
   }else {
      cout << "Element not present !!!" << endl;
   }

   return 0;
}
輸出
55 Element found !!!

C++中的max_element()和min_element()

max_element()和min_element()用於在給定元素範圍內查詢最大值和最小值。

語法

max_element (firstIterator, lastIterator);
min_element (firstIterator, lastIterator);

示例

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main(){
   vector<int> v = {999, 1252, 3117, 122222 , 10, 88, 2, 9, 45, 82, 546, 42, 221 , -1};

   cout << "Maximum Element: " << *max_element(v.begin(),v.end())<<endl;
   cout<<"Minimum Element: "<<*min_element(v.begin(),v.end()) <<"\n";
   return 0;
}
輸出
Maximum Element: 122222
Minimum Element: -1

C++中的for_each()

for_each()演算法用於對容器中的一系列元素應用給定的操作或指令。

語法

for_each (firstIterator, lastIterator, unaryFunction);

示例

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main(){
   vector<int> vec1 = { 1, 2, 3, 4, 5 };

   for_each(vec1.begin(), vec1.end(), [](int& i){
      i++;
   });

   for(int i:vec1) cout<<i<<" ";
      cout<<endl;

   return 0;
}
輸出
2 3 4 5 6 

C++中的swap()

swap()演算法用於就地將一個元素替換為另一個元素,因此元素交換位置。

語法

swap(container1,container2)

示例

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

int main() {

   vector<int> vec1 = {1, 2, 3};
   vector<int> vec2 = {4, 5, 6};

   swap(vec1,vec2);
   cout<<"vec 1: "<<endl;
   for(int i:vec1) cout<<i<<" ";
      cout<<endl;

   cout<<"vec 2: "<<endl;
   for(int i:vec2) cout<<i<<" ";
      cout<<endl;
   return 0;
}
輸出
vec 1: 
4 5 6 
vec 2: 1 2 3 

C++ STL中的迭代器

迭代器可以被認為是用於順序迭代容器的指標。這些迭代器在C++中使用``標頭檔案包含。

每個容器都有自己的迭代器。為了避免混淆,在遍歷容器時,可以使用`auto`關鍵字定義迭代器。

迭代器有五種型別:

示例

#include <bits/stdc++.h>
using namespace std;

int main(){
   vector<int> myvec={1,5,2,4,3,6,6,9,8};
   set<int>set(myvec.begin(),myvec.end());

   for(auto itr:myvec) cout<<itr<<" ";
      cout<<endl;
   for(auto itr:set) cout<<itr<<" ";
      cout<<endl;

   return 0;
}

輸出

1 5 2 4 3 6 6 9 8 
1 2 3 4 5 6 8 9 
廣告