# Vector
###### tags: `stl`
---
> 最常用的 STL 容器
##### 標頭檔
```cpp=
#include<vector>
```
Vector 就如同陣列,利用下標來存取的容器
相對於宣告就不可變的陣列
Vector 可以用 `push_back` 來自由伸縮改變大小
但陣列仍有它的優勢
例如程式碼短 常數小等等
但 Vector 的另一個好處在於
同其他 STL 容器它能開比陣列大非常多的容量
所以當資料龐大陣列沒辦法開時,就可以用 Vector
### 特色
- 為可變大小的序列容器
- 支援隨機 ( 用下標 ) 存取 $O(1)$
- 尾端增刪元素很快 $O(1)$
- 中間增刪元素很費時 $O(n)$
---
## 實作
### 宣告
宣告時會自動初始化為 0
也就是沒有指定的話每一項一開始都會是 0
##### 基本宣告
```cpp=
vector<int> vec1; //宣告空vec1,後續再用push_back增加元素
vector<int> vec2(10); //宣告長度為10的vec2,且每一項皆為0
```
##### 其他方式
```cpp=
vector<int> vec1 = {1, 2, 3}; //1 2 3
vector<int> vec2(5, 1); //1 1 1 1 1
vector<int> vec3(vec2); //複製vec2
vector<int> vec4(vec2.begin(), vec2.end());
//利用迭代器指定,這種方式可以指定頭尾,而上述寫法也是複製vec2
```
### Operator\[\]
也就是下標,用於存取元素
若添加時長度不夠,則會自動配置記憶體
常用於解決未知資料量的窘境
要注意 code 是從 0 開始計算
```cpp=
vector<int> vec = {1, 2, 3, 4, 5};
cout << vec[0]; //1
cout << vec[3]; //4
```
### push_back/pop_back
`push_back` 會往 Vector 後方添加元素
括號中的元素需與 Vector 內容物型態一致
`pop_back` 則會刪除最尾端的元素
ex:
```cpp=
vector<int> vec;
vec.push_back(1); //1
vec.push_back(2); //1 2
vec.push_back(3); //1 2 3
vec.pop_back(); //1 2
vec.push_back(1); //1 2 1
```
### size
取得當前容器的大小
```cpp=
vector<int> vec = {1, 2, 3, 4, 5};
cout << vec.size(); //5
//遍歷輸出vector
for(int i = 0; i < vec.size(); i++) {
cout << vec[i] << ' ';
}
```
### empty
判斷容器是否為空
如果是空的會回傳 `true`
裡面還有東西則回傳 `false`
注意這個檢查並不是檢查裡面是不是 0 之類的
就是檢查容器是不是什麼都沒有
```cpp=
vector<int> vec = {0, 0, 0, 0, 0};
cout << vec.empty(); //0 (false)
```
```cpp=
vector<int> vec;
cout << vec.empty(); //1 (true)
```
### clear
清空容器
讓容器變空
```cpp=
vector<int> vec = {1, 2, 3, 4, 5};
vec.clear();
cout << vec.empty(); //1 (true)
```
---
### 其他功能
- iterators
它可以迭代
- resize
重設容器的大小
- at
根據下標存取容器第 n 項的參照
- front
存取第一個元素
- back
存取最後一個元素
- data
存取第一項元素的指標
- assign
分配容器新的內容替換當前內容,並修改大小
- insert
插入
- erase
刪除指定迭代器的元素
- swap
交換兩個容器
- emplace
與 insert 相同,不過在傳入時呼叫建構元
- emplace_back
與 push_back 相同,不過在傳入時呼叫建構元
---
## 補充:二維 Vector
* Vector 裡面包 Vector
想法較為複雜
雖然沒有陣列直觀,但可以 `push_back`
而且在傳遞至函式中會複製而不是傳遞指標
---
#### 宣告, 初始化
```cpp=
vector<vector<int> > vec; //空二維vector
vector<vector<int> > vec(m, vector<int>(n)); //長 m 寬 n
vector<vector<int> > vec(m, vector<int>(n, 2)); //將每項都初始化成2
```
亦可透過 `resize` 函式初始化
```cpp=
vector<vector<int> > vec(m);
for(int i = 0; i < m; i++)
vec[i].resize(n);
//vec[i].resize(n, 2); 亦可初始化
```
---
#### 存取
* `vec[i][j]`
---
#### push_back
需先創建一個臨時一維 `vector` 再將它 `push_back` 進去
```cpp=
vector<vector<int> > vec;
for(int i = 0; i < m; i++) {
vector<int> row(n);
// for(int j = 0; j < n; j++) 亦可賦值
// cin >> row[j];
vec.push_back(row);
}
```