# 進階STL:vector ## 2021/11/19 電算社第九堂社課 --- ## STL ? standard template library(標準模板庫) 更多的資料結構 ---- 複習一下之前遇到的資料結構 std::string 字串 ex `string s = "C8763";` c-array (c式陣列) ex `int arr[100] = {0};` 除了這兩種,我們之後會學到更多種類的資料結構。 --- ## STL簡介 ---- 將來會學到的東西 一覽 `vector` `queue` , `stack` , `deque` `set` , `map` `priority_queue` (可能有更動) --- ## c-array ---- ```cpp= #include<iostream> using namespace std; int main() { int arr[10]; for(int i=0 ; i<10 ; i++) cin >> arr[i]; int found = 5 cout << arr[found]; } ``` ---- ### 缺點 1. 使用長度固定(size改不了) 2. 存取size之外的位置,程式會直接crash --- ## vector ---- What is "vector" -> 多功能陣列 ---- ### 標頭檔 ```cpp= #include<vector> ``` ---- ### 宣告 ```cpp= #include<vector> using namespace std; // 沒打的話,vector前面要加 std:: vector <type> name(size , memset); //最完整的寫法 // or vector <type> name(); // size = 0 , memset = 0 ``` ---- ### 初始化 ```cpp= #include<vector> #include<iostream> using namespace std; int main() { vector<int> v(10 , -1); // {-1,-1,-1,-1,-1,-1,-1,-1,-1-,-1} cout << v[9]; // -1 } ``` `Tips: 除了初始化,剩下的時候,c-array的用法,vector都可以用。` `但是 vector 多了很多功能` ---- ### 缺點 1. n維陣列宣告要打超長 (下面會詳細說明) 2. 要打標頭檔 `#include<vector>` --- ## 功能 ---- ### 空間相關功能 <font color="#FFF300">v.empty() : </font> if v 的 size 為 0 ,回傳 1 , else 回傳 0。 <font color="#FFF300">v.size() : </font> 輸出 v 的 size <font color="#FFF300">v.resize( , ) : </font> 重新分配空間 - 像是一開始初始化的`( , )` <font color="#FFF300">v.clear() : </font> 把 v 清空 ---- ```cpp= #include<iostream> #include<vector> using namespace std; int main() { vector<int> v(3,5); // 5 5 5 cout << v.empty() << " " << v.size() << "\n"; // 0 3 v.resize(5,2); // 2 2 2 2 2 v.clear(); // } ``` ---- ### 位置相關功能 (假設 v 的 size 為 5) v.front() : `v[0]` 的值 v.back() : `v[4]` 的值 v.begin() : `v[0]` 的**偽指標** v.end() : **`v[5]`** 的**偽指標** // 它常會跟其他功能一起用 ---- ```cpp= #include <iostream> #include <vector> using namespace std; int main(){ vector<int> v = {1,2,3,4,5,6,7,8,9,10}; cout << v.front(); // 1 cout << v.back(); // 10 cout << v.end() - v.begin(); // 10 (v.size()); } ``` ---- ### 資料相關功能 v.push_back() v.pop_back() ---- ```cpp= #include <iostream> #include <vector> using namespace std; int main(){ vector<int> v; // (size = 0) v.push_back(1); // 1 v.push_back(2); // 1 2 v.pop_back(); // 1 } ``` ---- ### Vector額外功能 刪除或新增中間的第 i 項 v.insert(v.begin() + i, a):在第 i 項插入a v.erase(v.begin() + i):把第 i 項移掉 ```cpp= #include<iostream> #include<vector> using namespace std; int main(){ vector<int> v(5); // size = 5 for(int i = 0 ; i < 5 ; i++) v[i] = 2 * i; // {0 , 2 , 4 , 6 , 8} v.erase(v.begin() + 0); // 2 4 6 8 v.erase(v.begin() + 2 , v.begin() + 3); // 2 4 8 v.insert(v.begin() + 1 , 5); // 2 5 4 8 } ``` --- ## algorithm x vector ---- ### sort ```cpp= #include <iostream> #include <vector> #include <algorithm> // sort的函式庫 using namespace std; int main(){ vector<int> v = {5,6,3,1,2,9,8,7,0,4}; sort(v.begin(), v.end()); for(int i = 0; i < 10; i++){ cout << v[i] << ' '; // 0 1 2 3 4 5 6 7 8 9 } sort(v.begin(), v.begin() + 5, greater<int>()); for(int i = 0; i < 10; i++){ cout << v[i] << ' '; // 4 3 2 1 0 5 6 7 8 9 } } ``` ---- ### upper_bound , lower_bound `upper_bound(v.begin() , v.end() , num);` 第一個 **大於** num 的偽指標(類似 `v.begin()` ); `lower_bound(v.begin() , v.end() , num);` 第一個 **大於等於** num 的偽指標(類似 `v.begin()` ); **使用前,陣列要先 <font color="#F00">由小到大</font> 排列過** ---- ```cpp= #include<iostream> #include<algorithm> #include<vector> using namespace std; int main() { vector<int> v(10); for(int i=0 ; i<10 ; i++) v[i] = i*2; // {0, 2, 4, 6, 8, 10, 12, 14, 16, 18} cout << upper_bound(v.begin() , v.end() , 14) - v.begin(); // 8 cout << lower_bound(v.begin() , v.end() , 14) - v.begin(); // 7 } ``` --- ### 二維陣列 ---- ```cpp= vector< vector<type> > name(size1 , vector<type>(size2 , memset)); type name[size1][size2]; ``` ---- ```cpp= #include <iostream> #include <vector> using namespace std; int main(){ vector<vector<int>> v(2, vector<int>(3, 2)); // { {2, 2, 2}, {2, 2, 2} } int arr[2][3]; for(int i = 0; i < 2; i++){ for(int j = 0; j < 3; j++){ arr[i][j] = i + j; } } // 0 1 2 // 1 2 3 } ``` --- ## 小練習 卡森社長找到了一個好玩的機器,上面有兩個按鈕,按1可以放入一顆球,按2可以從最前端射出一顆球,現在卡森社長要進行$n$輪操作,你可以幫他看看最終機器裡面剩下的球依序為何嗎 ---- 輸入說明:輸入一個整數$n$,代表會有$n$輪操作,接著輸入數字$m$,代表要按的按鈕,若$m = 1$,則輸入一個數字$k$,代表放入球的編號 輸出說明:輸出最後機器裡剩下的球依序為何 範例輸入: ``` 5 1 2 1 3 1 4 2 2 ``` 範例輸出:`4` ---- 我是防雷頁:D ---- ```cpp= #include <iostream> #include <vector> using namespace std; int main(){ vector<int> v; int n; cin >> n; for(int i = 0; i < n; i++){ int m; cin >> m; if(m == 1){ int k; cin >> k; v.push_back(k); } if(m == 2){ if(!v.empty()){ v.erase(v.begin() + 0); } } } for(int i = 0; i < v.size(); i++){ cout << v[i] << ' '; } return 0; } ``` --- ## OJ練習題 [zerojudge a104排序](https://zerojudge.tw/ShowProblem?problemid=a104)
{"metaMigratedAt":"2023-06-16T14:30:10.056Z","metaMigratedFrom":"YAML","title":"進階STL:Vector","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"theme\":null}","contributors":"[{\"id\":\"4f731eff-9d88-41f4-af56-2e3e02f20cfc\",\"add\":631,\"del\":154},{\"id\":\"9e7d687a-83f2-4e8a-8ee6-8846394e69a5\",\"add\":4612,\"del\":1994},{\"id\":\"68c94489-3c2e-4879-b847-e982f360b03c\",\"add\":2341,\"del\":119}]"}
    489 views