# STL(2) ## 11/10 社課 --- ## queue ---- 隊列、佇列 可以想像成排隊 每次都只能從最後面排隊,從最前面離開 先進先出(First in First out, FIFO) ---- 宣告 ```cpp= queue<data_type> q; ``` ---- 把資料加進 queue 裡(多一個人排隊) ```cpp= q.push(a); ``` 把最前端資料刪掉(最前面的人離開) ```cpp= q.pop(); ``` ---- 取得最前端的資料 ```cpp= q.front() ``` 清空 queue ```cpp= q=queue<data_type>(); ``` ---- 其實大部分 STL container 都可以用這種方式清空 ```cpp= vector<int> v; v=vector<int>(); ``` 如果這種 STL 沒有 clear() 那這會是一個好選擇 ---- 範例 ```cpp= queue<int> q; q.push(2); // {2} q.push(3); // {2, 3} q.push(6); // {2, 3, 6} cout << q.front(); // 2 q.pop(); // {3, 6} q=queue<int>(); // {} ``` --- ## stack ---- 堆疊 可以想像成疊盤子 每次都只能拿最上面的 後進先出(Last in First out, LIFO) ---- 宣告 ```cpp= stack<data_type> stk; ``` ---- 把資料加進 stack 裡(把一個盤子堆到最上面) ```cpp= stk.push(a); ``` 把最頂端的資料刪掉(把最上面的盤子拿走) ```cpp= stk.pop(); ``` ---- 取得最頂端的資料 ```cpp= stk.top() ``` 清空 stack ```cpp= stk=stack<data_type>(); ``` ---- 範例 ```cpp= stack<int> stk; stk.push(2); // {2} stk.push(3); // {2, 3} stk.push(6); // {2, 3, 6} cout >> stk.top(); // 6 stk.pop(); //{2, 3} stk=stack<int>(); // {} ``` --- ## priority_queue ---- 優先佇列 權重越大的排前面 預設為數值大的排前面 實作是 [heap](https://reurl.cc/l72ygA) ---- 宣告 ```cpp= priority_queue<data_type> pq; // 預設取數值最大的 priority_queue<type, vector<type>, greater<type>> pq2; // 取數值最小的 priority_queue<type, vector<type>, cmp> pq3; // 自定義排序 ``` ---- 資料結構中自定義排序 ```cpp= struct cmp{ bool operator()(type a, type b){ return //... } }; ``` ```cpp= struct cmp{ bool operator()(string a, string b){ return a.size()<b.size(); } }; ``` priority_queue 最終取到的會是權重最大的 在以上範例就是字串長度最大的 ---- 把資料加進去 ```cpp= pq.push(a); ``` 把權重最大的資料刪掉 ```cpp= pq.pop(); ``` ---- 取得權重最大的資料 ```cpp= pq.top() ``` 清空 priority_queue ```cpp= pq=priority_queue<...>(); ``` ---- 範例 ```cpp= priority_queue<int> pq; pq.push(3); // {3} pq.push(6); // {3, 6} pq.push(2); // {2, 3, 6} cout << pq.top(); // 6 pq.pop(); // {2, 3} pq=priority_queue<int>(); // {} ``` 實際上他內部位置的操作不是這樣 就只是方便各位理解 --- ## set ---- 集合 就和數學上的集合類似 元素藉權重由小排到大(預設為數值小到大) 一個集合裡的每個元素最多只會出現一次 實作 [紅黑樹](https://reurl.cc/ka2MrK) ---- 宣告 ```cpp= set<data_type> s; set<data_type, cmp> s2; // 自定義排序 ``` ---- 把元素加進去 ```cpp= s.insert(a); ``` 把元素刪除 ```cpp= s.erase(a); ``` ---- 查詢元素位置 ```cpp= s.find(a); ``` 這會回傳 iterator,類似指標 如果沒有這個元素則會回傳 s.end() 我們也可以用以判斷是否在 set 中 ```cpp= if(s.find(a)!=s.end()){ //... } // 如果找的到 a -> set 裡面有存在 a ``` ---- 清除 set ```cpp= s.clear(); ``` ---- 可以用 prev(iter), next(iter) 找到某個 iterator 前後一個的 iterator ```cpp= set<int> s; s.insert(1); s.insert(2); s.insert(4); cout << *prev(s.find(2)); // 1 cout << *next(s.find(2)); // 4 ``` ---- 類似的資料結構 [multiset](https://cplusplus.com/reference/set/multiset/) 可以存在相同元素 [unordered_set](https://cplusplus.com/reference/unordered_set/unordered_set/) 不排序的 set --- ## map ---- 鍵值對(key-value pair) 對於每個 key 都有一個對應的 value 其實就是一個放 pair 的 set 按照 key 排序 ---- 宣告 ```cpp= map<data_type_1, data_type_2> mp; ``` ---- 加入一個健值對 ```cpp= mp[key]=val; mp.insert(make_pair(key, val)); ``` 刪除某個 key ```cpp= mp.erase(key); ``` 拿到某個 key 的 value ```cpp= mp[key] ``` ---- 查詢是否存在某個 key(回傳布林值) ```cpp= mp.count(key); ``` 清空 map ```cpp= mp.clear(); ``` ---- map 在還沒加入某個 key 時就呼叫他的話 電腦會給他一個預設值,之後將他們加進 map 中 ```cpp= map<int, int> mp; cout << mp.count(1); // 0 cout << mp[1]; // 0 cout << mp.count(1); // 1 ``` ---- 類似的資料結構 [multimap](https://cplusplus.com/reference/map/multimap/) ~~其實我不知道這是幹嘛的~~ [unordered_map](https://cplusplus.com/reference/unordered_map/unordered_map/) 不排序,比 map 快一點 ---- 以上共用的東西 .size() 回傳大小 .empty() 回傳是否為空 --- 今天講的內容很多 各位加油 如果把這部分熟悉 你就脫離新手期了!
{"description":"type=slide","title":"11/10 C++社課","contributors":"[{\"id\":\"1a0296c8-ce58-4742-acda-22c02ae81a74\",\"add\":3683,\"del\":56}]"}
    182 views