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个元素
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 有额外的管理开销)