---
# System prepended metadata

title: Vector 向量
tags: [程設班講義]

---

# 簡介
其為STL(Standard Template Library)清單中之陣列，跟傳統陣列差別在可不預先設置大小，但其需先引入函式。
```cpp=
#include <vector>
```

# 語法
設置vector時，使用左箭頭與右箭頭包住資料型態。
```cpp=
vector<變數型態> 名稱;
vector<int> vec1;
vector<int> vec2(n);                 //大小為n。
vector<int> vec3(n, 1);              //大小為n，每個值預設為1。
vector<int> vec4 = {1, 2, 3, 4, 5};  //自動調整大小為5。

//二維vector。
vector<vector<int>> vec5(m, vector<int>(n, 1));   // m行，n列，每個值預設為1。 
```

---

<font color="#EB6E41">與傳統陣列一樣</font>，利用`[ ]`來取得陣列位置中的資料。
```cpp=
vector<int> vec(3);
for(int i = 0; i < 3; i++)
    cin >> vec[i];  //輸入1 2 3。
cout << vec[0] << ' ' << vec[1] << ' ' << vec[2];  //輸出1 2 3。
```

:::info
::: spoiler .at()
因為他的功能跟傳統陣列的`[ ]`幾乎一樣，所以放在這不放在內建函式。
```cpp=
vector<int> vec(3);
for(int i = 0; i < 3; i++)
    cin >> vec.at(i);  //輸入1 2 3。
cout << vec.at(0) << ' ' << vec.at(1) << ' ' << vec.at(2);  //輸出1 2 3。
```
他會執行邊界檢查，如果索引超出範圍，會回傳`std::out_of_range` 。
```cpp=
vector<int> vec = {1, 2, 3};
cout << vec.at(5) ; //輸出 std::out_of_range 。
```
:::

# 內建函式
## .size() & .capacity() 
`.size()` 和 `.capacity()` 皆可取得陣列大小。

```cpp=
vector<int> vec(10);
cout << vec.size() << '\n';  //輸出 10。
cout << vec.capacity() << '\n';  //輸出 10。
```

前者看的是元素數量，後者看的是容器大小，配合 `.resize()` 和 `.reserve()` 可看出差異。

## .empty() 
`.empty()` 在容器內部是空的時傳回 `true` 。

```cpp=
vector<int> vec;
cout << (vec.empty()) << '\n';  //輸出 1。
```

## .front() & .back()
`.front()` 可以存取 (<font color="#EB6E41">不移出</font>) 向量頭端的元素，`.back()` 可以存取 (<font color="#EB6E41">不移出</font>) 尾端的元素。
```cpp=
vector<int> vec = {3, 4, 5, 6, 7};
cout << (vec.front() = 4);   //輸出 4。
cout << (vec.back() = 8);    //輸出 8。
cout << (vec.front() == 4);  //輸出 1。
cout << (vec.back() == 7);   //輸出 0。
```

## .push_back() & .emplace_back()
在容器的尾端增加元素。

`push_back`會先複製一個欲新增的元素再加入到容器尾端，接著把複製的元素刪除。

`emplace_back`會直接在容器最後新增一個位置，值設為指定的值。

所以大部分時候`emplace_back`的運行速度較快(沒差多少)，但建議用`push_back`會比較好，因為`emplace_back`會在該錯誤時沒有報錯。

```cpp=
vector<int> vec;
vec.push_back(10);  // vec = {10}。
vec.push_back(20);  // vec = {10, 20}。
```

## .pop_back()
刪除容器的尾端元素。

```cpp=
vector<int> vec = {1, 2, 3, 4, 5};
vec.pop_back();   // vec = {1, 2, 3, 4}。
vec.pop_back();   // vec = {1, 2, 3}。
```

## .insert() & .erase()
`.insert()`在容器中的指定位置插入，若插入元素的條件為 n，則在後一項輸出 n 個數值 。(若不含插入元素則預設為1。)

`.erase()`刪除容器中中的指定位置，直到結束的位置。(若不含結束的位置則預設為1。)

需要配合疊代器(iterator)，看看就好，基本的資料存取用不到。
```cpp=
vec.insert(插入的位置，(插入多少元素)， 數值)
vector<int> vec = {1, 2, 3};
vec.insert(vec.begin() + 1, 7);    // vec = {1, 7, 2, 3}。
vec.insert(vec.end(), 2, 4);       // vec = {1, 7, 2, 3, 4, 4}。

v.erase(刪除的位置，(結束的位置))
vector<int> v = {1, 2, 3, 4};
v.erase(v.begin() + 1);               // vec = {1, 3, 4}。
v.erase(v.begin(), v.begin() + 2);  // vec = { }。
```

## .clear()
清除vector中的所有元素。
```cpp=
vector<int> vec = {1, 2, 3};
vec.clear();
```

## .resize() & .reserve() 
`.resize()` 和 `.reserve()` 皆可調整陣列大小。

`.resize()` 的新大小若大於當前大小，會新增元素，反之則會移除多餘的元素。

```cpp=
vector<int> vec = {1, 2, 3};
vec.resize(5);    // vec = {1, 2, 3, 0, 0} 。
vec.resize(2);    // vec = {1, 2} 。

vector<int> v;
v.reserve(10); 
cout << v.capacity() ;  // 輸出 10。
cout << v.size() ;      // 輸出 0。

v.push_back(1);         // 新增元素。

cout << v.capacity() ;  // 輸出 10。
cout << v.size() ;      // 輸出 1。
```

再說一次，前者看的是元素數量，後者看的是容器大小。

# 例題
沒有例題，自己去 [array 陣列](https://hackmd.io/@PoteLiu/BkInPx92R) 找。

###### 都看到這了難道不按個愛心支持一下嗎?