STL學習筆記

寫在前面

其實之前是分着寫過筆記的,不過感受那樣太麻煩了還不如一塊兒寫,全部就有了這篇博客算法

STL 簡介

STL,全稱 Standard Template Library,標準模板庫,分爲「容器」、「迭代器」、「算法」等六部分。 OI中經常使用的是「容器」及「算法」,這裏對這兩部分作簡要介紹。 OI經常使用的容器有: vector, queue, stack, deque, priority_queue, set, map 等;除 priority_queue 在 < queue > 中以外它們都在與本身同名的頭文件裏。數組

vector

vector是一個經常使用的變長數組實現。要定義一個 A 類型的 vector,能夠 vector < A > v; 它的一些函數以下:
v[i] 訪問第 i 個元素(能夠修改,i 從 0 開始)(注意,越界時會 RE);
v.front() v.back() 訪問第一個元素/最後一個元素;
v.begin() v.end() 返回 v 的首尾迭代器,能夠傳給 sort / reverse 等函數;
v.size() 返回 v 的長度;
v.empty() 若 v 爲空則返回 true,不然返回 false,等價於 (v.size() == 0);
v.clear() 清空內容(並將 size() 重置成 0);
v.push_back(x) 將 x 添加到 v 的末尾(會把 size 變大);
v.pop_back() 將 v 的末尾彈出(會把 size 變小);
v1 < v2, v1 > v2 等比較運算符,比較兩個同類型 vector 的字典序。函數

vector是能夠存圖的,咕咕咕spa

#include<iostream>
#include<vector>
using namespace std;
vector<int>q[520];
int main() {
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=m; ++i) {
        int x,y;
        cin>>x>>y;
        q[x].push_back(y);
    }
    for(int i=1; i<=n; ++i) {
        for(int j=0; j<q[i].size(); ++j) {
            cout<<q[i][j]<<" ";
        }
        cout<<'\n';
    }
    return 0;
}

queue

queue,即隊列,能夠用 queue < A > q; 聲明。
q.front() q.back() 訪問隊首/隊尾元素;
q.push(x) 將 x 插入隊尾;
q.pop() 從隊首彈出;
q.empty() 判斷隊列是否爲空;
q.size() 返回隊列裏元素個數。
注意,queue 沒有 clear,對此能夠
while (!q.empty()) q.pop();指針

stack

stack,棧,能夠用 stack < A > st; 聲明。
st.top() 訪問棧頂元素;
st.push(x) 將 x 入棧;
st.pop() 從棧頂彈出;
st.empty() 判斷棧是否爲空;
st.size() 返回棧中剩餘的元素個數。
stack 的清空方式和 queue 相同。code

deque

q[i] 返回某個位置的元素(注意,這是 O(1) 的);
q.push_front(x) q.push_back(x) 從首/尾插入;
q.pop_front() q.pop_back() 從首/尾刪除;
q.front() q.back() 訪問首/尾的元素;
q.empty() q.size() q.clear() 和前面的同樣。
deque, queue, stack 的實現比較奇怪,不排除致使 MLE/TLE 的可能,建議考場手寫隊列(畢竟好寫)。排序

priority_queue

priority_queue < A > q; 定義一個大根堆,A 須要重載小於運算符。
q.top() q.pop() 訪問/彈出堆頂;
q.push(x) 插入元素。
若是聲明小根堆,能夠這樣:
priority_queue < A, vector < A > , greater < A > > q;
其中 greater 在 < functional > 裏定義隊列

有時候咱們想要讓 A 是 int,比較方式很奇怪,可是又不想把單個 int 封裝到結構體裏,這時候能夠這樣:ci

struct Cmp {
    bool operator(int a, int b) {
        return /* 返回 true 表示 b 更大,即 b 會先彈出 */;
    }
};
priority_queue  <int, vector<int>, Cmp> q;

set

set 按從小到大順序維護一個集合。set < A > s; 要求重載小於號。
s.empty() s.size() s.clear() 不用多說。
s.insert(x) 插入一個 x。若是 x 已存在那麼什麼都不作。
s.erase(x) 刪除 x。x 不存在則什麼都不作。
s.count(x) 若是 x 存在返回 true,不然返回 false。
s.find(x) 返回指向 x 的迭代器,不存在則返回 s.end()
s.lower_bound(x) 返回最小的大於等於 x 的元素的迭代器,不存在則返回 s.end()。要獲得這個元素的值能夠 *s.lower_bound(x);
s.upper_bound(x) 相似,返回最小的大於 x 的元素的迭代器。

相似 priority_queue,能夠把比較函數封裝到結構體裏而後 set < A, Cmp > s;

map

map 和 set 相似,可是它維護的每一個元素還有一個對應的「值」。map < A, B > m; 要求 A 類型重載了小於號。
m.empty() m.size() m.clear() 跟前面的同樣。
m[x] 訪問 x 這個元素對應的值。若是不存在會產生一個默認的值存進去(對於int,就會是0)。
m.erase(x) 刪除元素 x。x 不存在則什麼都不作。
m.count(x) 判斷 x 是否存在。
m.find(x) 返回指向 x 的迭代器,不存在則返回 m.end()
m.lower_bound(x) 返回最小的大於等於 x 的元素的迭代器,不存在則返回 s.end()。要獲得這個元素或它的值,能夠 m.lower_bound(x)- > first 或 m.lower_bound(x)- > second;
m.upper_bound(x) 相似,返回最小的大於 x 的元素的迭代器。

仍然能夠 map < A, B, Cmp > 。注意是 A 須要比較,B沒有什麼要求。

algorithm

algorithm 庫封裝了許多函數。 copy(A + l, A + r, B) 把 A 數組裏 [l, r) 開區間拷貝到 B 數組開頭。A+l, A+r 能夠換成 vector 的 v.begin(), v.end(), 或者 v.begin()+i。下同 fill(A + l, A + r, v) 把 A 數組裏 [l, r) 都賦值爲 v。 swap(x, y) 交換兩個元素。注意因爲大部分 stl 容器只包含一個指針,交換是 O(1) 的。 reverse(A + l, A + r) 翻轉區間 [l, r)。 sort(A + l, A + r) 排序區間 [l, r)。 unique(A + l, A + r) 把區間裏連續的相同的元素移至末尾,返回剩下的元素結尾位置。 int m = unique(A, A + n) – A; nth_element(A + l, A + k, A + r) 把 [l, r) 部分排序,使得 A[k] 這個位置的元素是正確的,比它小的在左邊而比它大的在右邊。 好比 nth_element(A, A + 5, A + 10) 會把第 6 小的(注意從 0 開始)放到 A[5],前 5 小以任意順序放到 A[0...4],其餘以任意順序放到 A[6...9] lower_bound(A + l, A + r, x) 返回第一個大於等於 x 的位置(要求序列有序)。取其下標能夠 lower_bound(A + l, A + r, x) – A; upper_bound 同理,返回第一個大於 x 的位置。 binary_search(A + l, A + r, x) 二分查找判斷 x 是否在這個區間裏出現,只返回true/false

相關文章
相關標籤/搜索