# 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 | 禁止商業用途 | 轉載標記出處 | 改編作品必須在相同條款下分享。