來源:blog.csdn.net/qq_41575507/article/details/113864734
概述STL 是「Standard Template Library」的縮寫,中文譯為「標準模板庫」。STL 是 C++ 標準庫的一部分,不用單獨安裝。
C++ 對模板(Template)支持得很好,STL 就是藉助模板把常用的數據結構及其算法都實現了一遍,並且做到了數據結構和算法的分離。例如,vector 的底層為順序表(數組),list 的底層為雙向鍊表,deque 的底層為循環隊列,set 的底層為紅黑樹,hash_set 的底層為哈希表。
STL 從根本上講是「容器」的集合,也是組件的集合。容器包括 list、vector、set、map 等;組件包括迭代器等。STL 的目的是標準化組件。
STL 是 C++ 的一部分,不用額外安裝,被內建在支持 C++ 的編譯器中。
STL 的算法是標準算法,其實現了將已經定義好的算法應用在容器的對象上。
刷題時常用的STL通過概述可以了解到STL 就是藉助模板把常用的數據結構及其算法都實現了一遍,並且做到了數據結構和算法的分離。所以在刷題時配合使用 STL 可以極大的提高做題的速度。可以根據情況來選擇使用 STL 來做題目,如果題目對時間要求比較高的話可以不使用 STL,比如棧和隊列可以使用數組來進行模擬等等。一般情況下可以直接選擇使用STL來做題目。
vector初始化.在定義時初始化vector的長度
vector 可以一開始不定義大小,之後用 resize 方法分配大小,也可以一開始就定義大小,之後還可以對它插入刪除動態改變它的大小。不管在 main 函數裡還是在全局中定義,它都能夠直接將所有的值初始化為0 (不用顯式地寫出來,默認就是所有的元素為0)
注意:系統為某一程序分配空間時所需的時間與空間大小無關,而與分配的次數有關。所以儘量減少申請空間的次數,也有利於提到程序的效率。
在vector的擴展大小中有一個 倍增思想:假如vector的實際長度為 n ,m為vector當前的最大長度,那麼在加入一個元素的時候,先看一下,假如當前的 n = m,則再動態申請一個 2m 大小的內存。反之,在刪除的時候,如果 n ≤ m ÷ 2 m\div2m÷2,則再釋放一半的內存。基於該思想,如果長度為 n 的vector數組,假設一開始只申請了一個空間,那麼最後其申請的次數是 l o g ( n ) log(n)log(n) 的,所以vector是一種效率比較高的數組。
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v(10); for (int i = 0; i < 10; i++) cout << v[i] << ' '; return 0;}#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v(10, 9); for (int i = 0; i < 10; i++) cout << v[i] << ' '; return 0;}#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v[10]; int cnt = 1; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { v[i].push_back(cnt++); } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { cout << v[i][j] << ' '; } cout << endl; }
return 0;}#include<iostream>#include<vector>using namespace std;
int main() { vector<vector<int> > v; int cnt = 1; for (int i = 0; i < 5; i++) { vector<int> q; int x; cin >> x; while (x != -1) { q.push_back(x); cin >> x; } v.push_back(q); } cout << "輸出的結果為:" << endl; for (int i = 0; i < v.size(); i++) { for (int j = 0; j < v[i].size(); j++) { cout << v[i][j] << ' '; } cout << endl; }
return 0;}size()
size() :返回vector中元素的個數,時間複雜度 O(1)。
注意: 對於順序容器size() 的時間複雜度為 O(1),對於list之類的節點容器,可能是線性時間即 O(n)。所以在 for 循環中需要求長度時最好把 size() 放到循環之外求,這樣可以在一些情況下將算法的時間複雜度由 O(n 2 n^2n
2 ) 降到 O(n)。
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v(10, 9); cout << "數組中元素的個數為:" << v.size() << endl; int len = v.size(); for (int i = 0; i < len; i++) cout << v[i] << ' '; return 0;}empty()empty() :v.empty() 檢查數組 v 是否為空。若容器為空則返回 true ,否則返回 false
push_back()向vector的最後插入一個元素
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); for (int i = 0; i < 3; i++) cout << v[i] << ' '; return 0;}pop_back()刪除vector的最後一個元素
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); for (int i = 0; i < 3; i++) cout << v[i] << ' '; cout << endl; v.pop_back(); for (int i = 0; i < 3; i++) cout << v[i] << ' '; cout << endl; for (int i = 0; i < v.size(); i++) cout << v[i] << ' '; return 0;}通過以上實驗可知,使用 pop_back() 並不是真正的將最後一個元素刪除了,只是修改了vector的末尾指針。
clear()清空數組中的所有元素
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); cout << "數組的元素個數為:" << v.size() << endl; for (int i = 0; i < v.size(); i++) cout << v[i] << ' '; cout << endl; v.clear(); cout << "數組的元素個數為:" << v.size(); return 0;}front()、back()front()訪問vector的第一個元素,back() 返回最後一個元素。
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); cout << "數組的第一個元素為:" << v.front() << endl; cout << "數組的最後一個元素為:" << v.back() << endl; return 0;}begin()、end()begin() 返回指向容器首元素的迭代器。若容器為空,則返回的迭代器將等於 end() 。end() 返回指向容器末元素後一元素的迭代器,即指向vector中最後一個元素之後的一個元素。此元素表現為佔位符;試圖訪問它導致未定義行為。
operator[]vector支持隨機尋址,像數組一樣。operator[pos]返回位於指定位置 pos 的元素的引用。不進行邊界檢查。在上面的例子中已經用到很多次了,比如: v[i] 表示訪問vector中下標為 i 的元素。這裡就不再演示了。
vector的三種遍歷方式使用隨機尋址的方式遍歷
範圍遍歷
迭代器方式遍歷
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> v; for (int i = 0; i < 10; i++) v.push_back(i); for (int i = 0; i < v.size(); i++) cout << v[i] << ' '; cout << endl; for (int i : v) cout << i << ' '; cout << endl; for (vector<int>::iterator i = v.begin(); i != v.end(); i++) cout << *i << ' '; return 0;}支持比較運算vector可以支持比較運算,可以直接比較兩個vector的大小。vector支持 ==, !=, <, <=, >, >= 運算符。
檢查兩個vector的內容是否相等,即它們是否擁有相同數量的元素且 vector1 中每個元素與 vector2 的同位置元素比較相等。
按 字典序 比較 vector1 與 vector2 的內容。
#include<iostream>#include<vector>using namespace std;
int main() { vector<int> a(6, 5), b(5, 6); if (a > b) cout << "a > b"; else cout << "b > a"; return 0;}pairpair 是一個結構體模板,其可於一個單元存儲兩個相異對象。
定義方式pair 的定義方式為:pair<int, int>,其中的兩個參數可以是任意的,比如 int、string、double、float 等等。
初始化可以在定義pair的時候直接初始化pair。
#include<iostream>using namespace std;
int main() { pair<int, string> p(1, "AC-fun"); cout << p.first << ":" << p.second; return 0;}構造pairpair 有兩種構造方式:
使用 make_pair() 創建一個 pair 對象,其類型根據各實參類型定義。
#include<iostream>using namespace std;
int main() { pair<int, string> p; p = make_pair(1, "AC-fun"); cout << p.first << ":" << p.second; return 0;}在 C++ 11 中還可以直接構造。
#include<iostream>using namespace std;
int main() { pair<int, string> p; p = {1, "AC-fun"}; cout << p.first << ":" << p.second; return 0;}訪問pair 以 first 為第一個關鍵字,以 second 為第二個關鍵字。例如現在已經構造好了一個 pair<int, string> p(1, "AC-fun"); 可以使用 p.first 訪問第一個關鍵字,使用 p.second 訪問第二個關鍵字。
#include<iostream>using namespace std;
int main() { pair<int, string> p(1, "AC-fun"); cout << p.first << ":" << p.second; return 0;}支持比較運算pair 與 vector 一樣,也是可以支持比較運算的。pair支持 ==, !=, <, <=, >, >= 運算符。按照 字典序 進行排序。
嵌套pair如果有一種東西有三種屬性,可以使用嵌套的pair來存儲。比如:
pair<int, pair<int, string> >stack在開頭提到了可以使用數組模擬棧,這裡就只貼一下代碼。
使用數組模擬棧#include<iostream>#include<string>using namespace std;
const int N = 100010;int stk[N], tt;
void add(int x) { stk[tt++] = x;}
void remove() { tt--;}
int top() { return stk[tt - 1];}
bool ept() { if (tt) return false; else return true;}
int main() { int n; cin >> n; while (n--) { string op; int x; cin >> op; if (op == "push") { cin >> x; add(x); } else if (op == "pop") { remove(); } else if (op == "empty") { if (ept()) { cout << "YES" << endl; } else { cout << "NO" << endl; } } else { cout << top() << endl; } }
return 0;}queue這裡就只貼一下數組模擬隊列的代碼。
使用數組模擬隊列
#include<iostream>#include<string>using namespace std;
const int N = 100010;int q[N], front, tail;
void add(int x) { q[tail++] = x;}
void remove() { front++;}
bool ept() { if (front == tail) return true; return false;}
int qey() { return q[front]; }
int main() { int n; cin >> n; while (n--) { string op; int x; cin >> op; if (op == "push") { cin >> x; add(x); } else if (op == "pop") { remove(); } else if (op == "empty") { if (ept()) cout << "YES" << endl; else cout << "NO" << endl; } else { cout << qey() << endl; } } return 0;}未完待續~~~~~~~~