GESP 6级

vector 容器

6级 · 指针/STL/复杂度
💡 为什么重要

vector 是 C++ 标准模板库(STL)中最常用的容器,堪称"万能动态数组"。它比普通数组更灵活——大小可以动态变化,还能随时插入、删除。GESP 6级考试中,几乎所有涉及"动态数组"的题目都推荐用 vector。掌握 vector 是使用 map、set、deque 等其他 STL 容器的基础。

📖 前置知识
  • 普通数组的声明和使用
  • #include 头文件的概念
  • for 循环的基本用法
  • (加分项)了解 new/delete 动态数组
🔍 vector 是什么?

vector 就是一个可以自动伸缩的数组。普通数组大小固定,vector 可以随时增加或减少元素,而且自动管理内存(不需要手动 new/delete)。

使用 vector 需要包含头文件:#include <vector>

📐 常用操作速查表
vector<int> v; // 创建空vector
v.push_back(x) // 在尾部添加元素x
v.pop_back() // 删除尾部最后一个元素
v.size() // 返回元素个数
v.empty() // 是否为空(true/false)
v[i] // 用下标访问(从0开始)
v.at(i) // 安全访问(越界会报错)
v.front() // 第一个元素
v.back() // 最后一个元素
v.clear() // 清空所有元素
v.insert(v.begin()+k, x)// 在第k个位置插入x
v.erase(v.begin()+k) // 删除第k个元素
💻 代码详解
📝 示例1:vector 的创建和基本操作
#include <iostream>
#include <vector>          // 必须包含这个头文件
using namespace std;

int main() {
    // 1. 创建空vector
    vector<int> v;           // 空的,里面没有元素

    // 2. 用 push_back 逐个添加元素
    v.push_back(10);          // v: {10}
    v.push_back(20);          // v: {10, 20}
    v.push_back(30);          // v: {10, 20, 30}

    // 3. 查看大小
    cout << "大小: " << v.size() << endl;
    // 输出: 大小: 3

    // 4. 用下标访问(和数组一样)
    cout << v[0] << endl;    // 输出10
    cout << v[1] << endl;    // 输出20
    cout << v[2] << endl;    // 输出30

    // 5. 用 for 循环遍历
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    cout << endl;             // 输出: 10 20 30

    // 6. 删除尾部元素
    v.pop_back();              // 删除30
    cout << "删除后: " << v.size() << endl;
    // 输出: 删除后: 2

    return 0;
}
📝 示例2:范围 for 循环和初始化
#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 1. 用初始化列表创建vector
    vector<int> v = {1, 2, 3, 4, 5};

    // 2. 范围 for 循环(最简洁的遍历方式)
    for (int x : v) {          // x 依次是 v 中的每个元素
        cout << x << " ";     // 注意:x 是副本,修改x不影响v
    }
    cout << endl;              // 输出: 1 2 3 4 5

    // 3. 如果要修改元素,用引用
    for (int &x : v) {         // x 是元素的别名
        x *= 2;                 // 每个元素都乘2
    }
    for (int x : v) {
        cout << x << " ";     // 输出: 2 4 6 8 10
    }
    cout << endl;

    // 4. 创建指定大小并初始化
    vector<int> v2(5, 0);     // 5个元素,都为0
    // v2: {0, 0, 0, 0, 0}

    // 5. 创建指定大小(默认初始化)
    vector<int> v3(10);       // 10个元素,int默认为0
    cout << v3[0] << endl;    // 输出0

    return 0;
}
📝 示例3:vector 的插入和删除
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v = {10, 20, 30, 40, 50};

    // 在中间插入:在下标2的位置插入100
    // 插入前: {10, 20, 30, 40, 50}
    v.insert(v.begin() + 2, 100);
    // 插入后: {10, 20, 100, 30, 40, 50}
    // 从下标2开始的元素都往后移了一位

    for (int x : v) cout << x << " ";
    cout << endl;  // 输出: 10 20 100 30 40 50

    // 删除下标1的元素(即20)
    v.erase(v.begin() + 1);
    // 删除后: {10, 100, 30, 40, 50}

    for (int x : v) cout << x << " ";
    cout << endl;  // 输出: 10 100 30 40 50

    // 删除所有20~40之间的元素(条件删除)
    for (auto it = v.begin(); it != v.end(); ) {
        if (*it >= 20 && *it <= 40) {
            it = v.erase(it);  // erase返回下一个迭代器
        } else {
            ++it;
        }
    }

    for (int x : v) cout << x << " ";
    cout << endl;  // 输出: 10 50

    return 0;
}
📝 示例4:二维 vector(矩阵/网格常用)
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n = 3, m = 4;  // 3行4列

    // 创建 n 行 m 列的二维vector,初始值都为0
    vector<vector<int>> grid(n, vector<int>(m, 0));

    // 给某些位置赋值
    grid[0][0] = 1;    // 第0行第0列
    grid[1][2] = 99;   // 第1行第2列
    grid[2][3] = 42;   // 第2行第3列

    // 打印二维vector
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << grid[i][j] << "\t";
        }
        cout << endl;
    }
    // 输出:
    // 1   0   0   0
    // 0   0   99  0
    // 0   0   0   42

    // 动态添加一行
    grid.push_back({7, 8, 9, 10});  // 添加第4行

    cout << "新行数: " << grid.size() << endl;
    // 输出: 新行数: 4

    return 0;
}
⚠️ 易错点
  • 越界访问:v[v.size()] 是越界的!最大下标是 v.size()-1。用 v.at(i) 可以自动检查越界(越界时抛异常)
  • 在 for 循环中删除元素:直接在遍历时 v.erase(it) 会导致迭代器失效。正确做法是用 it = v.erase(it)(erase返回下一个有效迭代器)
  • pop_back 空 vector:对空 vector 调用 pop_back 是未定义行为,先用 empty() 检查
  • 忘记 #include <vector>:不包含头文件会报编译错误
  • 二维 vector 初始化写错:vector<vector<int>> v(n, m) 是错的!应该是 vector<vector<int>> v(n, vector<int>(m, 0))
  • range-based for 中修改元素:for (int x : v) 中 x 是副本,改 x 不影响 v。要用 for (int &x : v)
🎯 练习建议
  • 入门:创建一个 vector,push_back 5个数,用范围 for 遍历并求和
  • 进阶:让用户输入 n 个数存入 vector,找出最大值和最小值
  • 挑战:实现"去重"——输入若干数到 vector,删除重复元素后输出
  • 综合:用二维 vector 实现矩阵乘法
  • 思考:vector 和普通数组哪个更快?为什么?(提示:vector 有额外的管理开销)