---
# System prepended metadata

title: 【3-4】動態陣列 — vector

---

# 【3-4】動態陣列 — vector

在 [【3-1】一維陣列](https://hackmd.io/@LAfWxjSxRASps-4O_bppsA/SkIWNv0Eel)、[【3-3】二維陣列](https://hackmd.io/@LAfWxjSxRASps-4O_bppsA/rklX2HZHll) 我們學習到了陣列，但受限於一開始就要給定長度，有些時候我們是不知道長度是多少的，就會發生裝不下或者浪費記憶體空間的事情。有沒有什麼方法可以解決呢？

## vector

`vector` 是 STL（標準模板庫）中的一種容器，可以想成動態陣列。相較我們之前學習的陣列，`vector` 提供了「不需要預先設定大小」的優勢，並且可以很方便的插入或刪除陣列中任何位置的資料，讓我們看看 `vector` 的語法吧！

### 宣告
```cpp
// 一維陣列
vector<int> v1;                    // 空的 vector，元素類型為 int
vector<int> v2(10);                // 大小為 10 的 vector，元素初始值為 0
vector<int> v3(10, 5);             // 大小為 10 的 vector，所有元素初始值為 5
vector<int> v4 = {1, 2, 3, 4, 5};  // 初始化列表

// 二維陣列
vector<vector<int>> v5;            // 空的二維 vector，元素類型為 int
```
### Python對照
```python
v1 = []                 # 空的 list
v2 = [0] * 10           # 大小為 10，初始值為 0
v3 = [5] * 10           # 大小為 10，初始值為 5
v4 = [1, 2, 3, 4, 5]    # 初始化列表
v5 = []                 # 空的二維 list
```
### 插入資料
```cpp
v.push_back(5);              // 在 vector 的尾端插入元素 5
v.insert(v.begin(), 3);      // 在 vector 的開頭插入元素 3
v.insert(v.begin() + 2, 7);  // 在 vector 的第三個位置插入元素 7
```

`begin()` 是一種迭代器（iterator），在[【3-6】迭代器](https://hackmd.io/@LAfWxjSxRASps-4O_bppsA/S16spNGrxg) 會詳細介紹，目前可以把 `v.begin()` 看成 `v[0]` 就好了。
### Python對照
```python
v.append(5)            # 在尾端插入元素 5
v.insert(0, 3)         # 在開頭插入元素 3
v.insert(2, 7)         # 在第 3 個位置插入元素 7
```
### 刪除資料
```cpp
v.pop_back();                         // 刪除 vector 最尾端的元素
v.erase(v.begin());                   // 刪除 vector 開頭的元素
v.erase(iterator);                    // 刪除 vector 中 iterator 所指的元素
v.erase(v.begin()+1, v.begin() + 4);  // 刪除 vector 中第 2 ~ 4個元素
v.erase(iterator1, iterator2);        // 刪除 vector 中 iterator1 到 iterator2 的元素
v.clear();                            // 刪除所有元素
```
### Python對照
```python
v.pop()                # 刪除最後一個元素
del v[0]               # 刪除第一個元素
del v[1:4]             # 刪除第 2 到第 4 個元素
v.clear()              # 清空所有元素
```
### 其它
```cpp
v.size();      // 回傳 vector 目前的大小
v.resize(5);   // 調整 vector 大小為 5
swap(v1, v2);  // 交換兩個 vector 的元素
v.empty();     // 回傳一個 bool ，如果 vector 為空回傳 True，反之 False
```
### Python對照
```python
len(v)                 # 取得大小
v = v[:5]              # 裁切長度（或用 v.extend() 增長）
v1, v2 = v2, v1        # 交換兩個 list
len(v) == 0            # 判斷是否為空
```
### 輸入

* 當題目敘述有「第一行輸入一個整數 $\text{n}$ ，接下來有 $\text{n}$ 行的測試資料」時可以使用下方寫法。

傳統陣列版本：
```cpp=
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n; // 資料總數

    int a[n]; // 宣告一個大小為 n 的 陣列

    for (int i = 0; i < n; i++) {
        cin >> a[i]; // 讀取使用者輸入的數字
    }

    for (int i = 0; i < n; i++) {
        cout << a[i] << " "; // 輸出每個數字
    }

    return 0;
}
```

`vector` 版本：

```cpp=
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n; // 資料總數

    vector<int> v(n); // 宣告一個大小為 n 的 動態陣列

    for (int i = 0; i < n; i++) {
        cin >> v[i]; // 讀取使用者輸入的數字
    }

    for (int i = 0; i < n; i++) {
        cout << v[i] << " "; // 輸出每個數字
    }

    return 0;
}
```
### Python對照
```python=
n = int(input())
a = list(map(int, input().split()))  # 一次讀入多筆
```

* 當題目敘述有「測試資料有數筆，當輸入 0 時終止」時可以使用下方寫法。

```cpp=
#include <bits/stdc++.h>

using namespace std;

int main() {
    vector<int> v; // 宣告一個空的 vector
    int n;

    while (cin >> n) {
        if(n == 0){     // 預設終止條件為 0 (此處可以根據題目條件更改) 
            break;
        }
        
        v.push_back(n); // 將輸入的數字加入 vector
    }

    for (int i = 0; i < v.size(); i++) {  // 用 v.size() 來取得陣列大小
        cout << v[i] << " ";
    }

    return 0;
}
```

### Python對照
```python=
v = []
while True:
    n = int(input())
    if n == 0:
        break
    v.append(n)
```

## pair
正常來說，陣列中的每一格只能儲存一個資料，但有些時候測試資料會存在前後關聯性，例如說該產品的「成本」和「利益」，這時候分成兩個 `vector` 儲存，在進行某些操作時可能會出問題，像是排序，如果對「成本」進行小到大排序，利益就無法對齊原本的成本，但若使用 `pair` 來處理，就可以把這個產品的「成本」和「利益」綁在一起，移動的時候也一起搬，這樣就不會亂掉了！

### 範例

題目：請根據成本從低到高的順序，輸出每個產品的利益，數字之間用空格分隔。

| 產品編號 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 成本 | 50 | 60 | 30 | 10 | 80 | 40 | 90 |
| 利益 | 60 | 40 | 50 | 80 | 90 | 30 | 10 |

解題思路：先將產品按照成本排序，再依序輸出該產品的利益。

### 輸入

把成本跟利益輸入後，得到兩個一維陣列：

| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 成本 | 50 | 60 | 30 | 10 | 80 | 40 | 90 |

| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 利益 | 60 | 40 | 50 | 80 | 90 | 30 | 10 |

此時的 index +1 就會是產品編號。

### 照成本排序

| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 成本 | 10 | 30 | 40 | 50 | 60 | 80 | 90 |

你會發現，確實排序好了，但我不知道產品編號。只知道成本低到高分別是多少。

### 先 pair 再排序

所以這時候我們就要使用 `pair` 來幫助我們把兩個資料儲存成「一組」，放在一起。
(請注意，現在只有一個 `vector` ！但是這個 `vector` 的每一個格子可以存放兩個整數。)

| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 成本 | 50 | 60 | 30 | 10 | 80 | 40 | 90 |
| 利益 | 60 | 40 | 50 | 80 | 90 | 30 | 10 |

排序後得到：

| index | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| -------- | --- | --- | --- | --- | --- | --- | --- |
| 成本 | 10 | 30 | 40 | 50 | 60 | 80 | 90 |
| 利益 | 80 | 50 | 30 | 60 | 40 | 90 | 10 |

你會發現，同一個產品的成本和利益被綁在一起了，所以排序的時候會一起移動。

### 宣告
```cpp
vector<pair<int, int>> v;
```
![image](https://hackmd.io/_uploads/SJybx901Jl.png)

可以看到 `pair` 後的陣列的每格都可以儲存兩個資料。第一格叫 `.first`，第二格叫 `.second`，記得一定要加「`.`」喔！

### 範例程式
```cpp=
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n; // 有 n 筆資料
    cin >> n;

    vector<pair<int,int>> v(n);
	
	// 輸入
    for(int i = 0; i < n; i++){
        int x, y;
        cin >> x >> y;
        v[i] = {x, y};
    }
	
	// 輸出
    for(int i = 0; i < n; i++){
        cout << v[i].first << " " << v[i].second << endl;   
    }

    return 0;
}

```


### Python對照
```python=
n = int(input())
v = []

for _ in range(n):
    x, y = map(int, input().split())
    v.append((x, y))
	
for x, y in v:
    print(x, y)
```

---

聯絡方式：codecodefunny@gmail.com
最後編修時間：2025/11/14 子柚筆