# Vector 陣列那張有說到:C++中的陣列大小是不可更改的 可是如果我今天的陣列大小,是要隨著使用者的輸入去做更改,那該怎麼辦? 就會要用到這章就紹的 Vector `#include <vector>(長度, 初始值)` --- # 建立Vector ```Cpp= #include <iostream> #include <vector> // 引入 vector 的標頭檔案 using namespace std; int main() { vector<int> numbers; // 建立一個儲存整數的 vector,名稱是 numbers vector<int> A(5); // 建立一個長度為5的陣列A vector<int> B = {1,2,3} // 建立一個包含1,2,3的陣列B return 0; } ``` ### 建立預設為無限大的vector ```python const ll INF = 1e9; vector<ll> dp(target + 1, INF); ``` vector 還有很多內建函式,方便我們操作 # 操作 以下是一些常見的 vector 操作方法。 ## 長度 size ```cpp cout << "Vector 的大小是:" << numbers.size() << endl; ``` ## 寫入 push_back 寫法1 - 有先預設vector長度。 ```cpp= vector<int> li(9); for (int i=0;i<9;++i){ cin >> li[i]; } ``` 寫法二 - vector長度未知 `push_back` ```cpp vector<int> li; for (int i=0;i<9;++i){ int a; cin >> li.push_back(a); } ``` ### 根據輸入設定長度 resize() 因為如果一開始沒有給vector長度,那在將輸入直寫進時,就會要用`push_back()`,而不能用`li[i]`(比較省記憶體空間效能也比較好) `resize()`就是來解決這種問題的。 ```cpp= cin >> n; a.resize(n); for (int i = 0; i < n; i++) { cin >> a[i]; } ``` --- ## 取出 [],foreach :::warning C++不允許負索引,不像 Python可以直接li[-1]取出最後一個元素 ::: ```cpp= // 一般取出 li[0]; // 取出後面第n個 li[li.size()-n] ``` foreach loop ```cpp= for (auto i:li){ cout << i; } ``` --- ## 刪除 pop, remove, erase 1. 刪除最後一個元素 ```cpp v.pop_back(); // 刪掉第3個元素 ``` 2. 刪除指定位置 ```cpp v.erase(v.begin() + 2); // 刪掉第3個元素 ``` 3. 刪除範圍 ```cpp v.erase(v.begin() + 1, v.begin() + 4); // 刪掉 [1,4) 這一段 ``` 4. 清空整個 vector ```cpp v.clear(); ``` 5. 刪掉所有等於 k 的元素 ```cpp v.erase(remove(v.begin(), v.end(), k), v.end()); ``` 6. 刪除重複元素(排序後 unique) ```cpp sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); ``` --- ## 排序 sort ```cpp sort(list.begin(), list.end()); ``` 透過指標一一取出兩個值來比對,所以後面還可以寫lambda函式。 ```CPP // lambda - 由大到小 sort(li.begin(), li.end(), [](int a, int b){ return a > b; }); ``` 因為sort是原地排序,不會回傳新值,所以如果要將已經排序好的陣列給另外一個陣列: ```cpp vector<int> li2 = li; sort(li2.begin(), li2.end()); ``` --- ## 找最大 max `#include <algorithm>` ```cpp max_element(li.begin(), li.end()); ``` 回傳的是一個指標,所以通常會寫 ```cpp= int mx = *max_element(a.begin(), a.end()); ``` --- ## 是否存在 find 判斷該元素是否在vector中 ```c= for (i=n;i>0;i--){ if (find(ans.begin(), ans.end(), i)== ans.end()){ // 如果不在 li.push_back(i); } } ``` find() 給定開頭與結尾 iterator(指標) 後,會從開頭遍歷到結尾前,尋找是否有等於指定值的元素;如果找到就回傳該位置的 iterator,否則回傳 end()。 --- ## 尋找index 可以用find()跟distance()兩個函式。 ```cpp= int main() { vector<int> ans = {5, 3, 7, 2}; int x = 7; auto it = find(li.begin(), li.end(), x); cout << distance(li.begin(),it); // output: 2 } ``` # 建立二維陣列 vector 也可以建立「二維陣列」 ```cpp= #include <iostream> #include <vector> #include <cstdio> // 引入 scanf 所需的標頭檔案 using namespace std; int main() { // 建立 3x3 的二維 vector vector<vector<int>> matrix(3, vector<int>(3, 0)); // 初始值全為 0 // 使用者輸入數值 cout << "請輸入 3x3 的矩陣數值(共 9 個數字):" << endl; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { scanf("%d", &matrix[i][j]); // 透過 scanf 輸入數值 cin >> li[i][j]; } } // 輸出二維 vector cout << "二維 vector 的內容是:" << endl; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { cout << matrix[i][j] << " "; } cout << endl; } return 0; } ``` # 與 Vector有關的操作 ## 交換 swap :::info 如果要用swap交換row,只有vector可以,因為原生陣列會被視為指標 ::: 我們可以用swap來實現row的交換。 ## 分割字串 在C++ 中分割字串比較麻煩,要先getline讀取整行後建立指標stringstream 用while將指向的字放入vector中 ```cpp= string str; getline(cin, str); // 讀取整行 vector<int> r; // 存放分割後結果 stringstream ss(str);// 建立字串流 string tok;// 暫存每個分割出的數字 while (getline(ss, tok, ' ')) { // 以空格為分隔符號,逐一讀取字串 r.push_back(stoi(tok)); } ``` --- :::info 趁機宣傳一下我自己的個人網站跟Youtube頻道 !! **[個人網站](https://hyc.eshachem.com/) | [Youtube頻道](https://www.youtube.com/@Hy.C)** ::: @2025 Hy.C 陳毓 > Copyright ©Hy.C 陳毓 CC BY-NC-SA 4.0 | 禁止商業用途 | 轉載標記出處 | 改編作品必須在相同條款下分享。