C++ STL
Standard Template Library (STL) 是 C++ 之中最重要的函式庫,包含多項重要的元件:
- Containers: 各種儲存與操作資料的容器
- Algorithms: 各種高效的演算法
- Iterators: 用來依照某些邏輯存取容器內資料的存取器
- Function Objects: 提供將 function 做為參數傳入 function 的方法,可以幫助客製化演算法的行為
- Adapters: 可以用來修改 STL 內其他元件行為的工具
Containers
STL container 清單: https://cplusplus.com/reference/stl/
需要注意的 containers:
-
forward_list
: 只有向前指針的 linked list,比list
(具備前後指針) 使用更少的空間 -
priority_queue
: 用 heap 實作的 queue,最大的東西會在最前面-
一般用法:
int arr[6] = { 10, 2, 4, 8, 6, 9 }; priority_queue<int> pq; // pushing array sequentially one by one for (int i = 0; i < 6; i++) { pq.push(arr[i]); } // printing priority queue cout << "Priority Queue: "; while (!pq.empty()) { cout << pq.top() << ' '; pq.pop(); }
-
修改成最小在最前面:
int arr[6] = { 10, 2, 4, 8, 6, 9 }; priority_queue<int, vector<int>, greater<int>> gquiz(arr, arr + 6);
-
使用自製的 comparator:
class Foo { /* data */ }; class Comparator { public: bool operator() (Foo, Foo) { // Should the first one be in front of the second one? return true; } }; int main() { std::priority_queue<Foo, std::vector<Foo>, Comparator> pq; return 0; }
-
-
set
: sorted set,用紅黑樹實作 -
map
: sorted map,實作與set
相同 -
multiset
: 跟set
一樣是 sorted set,但可以存重複資料 -
multimap
: 跟map
一樣是 sorted map,但可以存重複的 key- 注意用
find(key)
只會拿到一個 key-value pair,如果想要抓出所有重複 key 的 pair,要使用equal_range(key)
equal_range(key)
回傳的是一個 pair,first
是 iterator 的開頭(lower bound, inclusive),second
是 iterator 的結尾 (upper bound, exclusive)
- 注意用
Algorithms
常用 algorithms:
-
sort(begin, end)
: 使用 IntroSort 進行排序-
IntroSort:先嘗試使用 quick sort。 如果發現 partition 差太多,改成用 heap sort。 如果 size 夠小,改成用 insertion sort。
-
基本用法:
int arr[] = {3, 5, 1, 2, 4}; sort(arr, arr + 5); vector<int> vec {3, 5, 1, 2, 4}; sort(vec.begin(), vec.end());
-
-
binary_search(begin, end, value)
: 使用 binary search -
reverse(begin, end)
: 反轉順序
Iterator
可以看 C++ Reference 官網的介紹,簡單明瞭: https://cplusplus.com/reference/iterator/
只要搞懂 Input, Output, Forward, Bidirectional, Random Access 這五種 iterator 的差異,跟他們的從屬關係就好。
Function Objects (Functors)
直接看一例子,這個例子是寫一個 class 幫所有 array 所有的 element 加上想要的數字:
#include <bits/stdc++.h>
using namespace std;
// A Functor
class increment
{
private:
int num;
public:
increment(int n) : num(n) { }
// This operator overloading enables calling
// operator function () on objects of increment
int operator () (int arr_num) const {
return num + arr_num;
}
};
// Driver code
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr)/sizeof(arr[0]);
int to_add = 5;
transform(arr, arr+n, arr, increment(to_add));
for (int i=0; i<n; i++)
cout << arr[i] << " ";
}
主要是提供了改寫 ()
行為的能力,所以讓一個 object 可以被像 function 一樣呼叫。
其他
Pairs
C++ STL 提供了 pair 可以使用:
// CPP program to illustrate Pair in STL
#include <iostream>
#include <utility>
using namespace std;
// Driver Code
int main()
{
// defining a pair
pair<int, char> PAIR1;
// first part of the pair
PAIR1.first = 100;
// second part of the pair
PAIR1.second = 'G';
cout << PAIR1.first << " ";
cout << PAIR1.second << endl;
return 0;
}
- Pair 可以被比較,會先比第一個再比第二個