---
# System prepended metadata

title: 7. Vector

---

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