1. 定义和初始化
1.1 空二维vector
#include <vector>
using namespace std;
vector<vector<int>> vec2d; // 完全空的二维vector
1.2 指定行数
vector<vector<int>> vec2d(3); // 3行,每行是空的vector
1.3 指定行数和列数
vector<vector<int>> vec2d(3, vector<int>(4)); // 3行4列,初始为0
vector<vector<int>> vec2d(3, vector<int>(4, -1)); // 3行4列,初始为-1
1.4 使用初始化列表(C++11)
vector<vector<int>> vec2d = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
2. 添加元素
2.1 添加行
vector<vector<int>> vec2d;
// 方法1:添加空行,然后添加元素
vec2d.push_back(vector<int>()); // 添加空行
vec2d[0].push_back(1); // 在第一行添加元素
vec2d[0].push_back(2);
// 方法2:直接添加一行元素
vec2d.push_back({3, 4, 5}); // 添加第二行,包含3个元素
// 方法3:使用emplace_back(C++11,效率更高)
vec2d.emplace_back(6, 7, 8); // 添加第三行
2.2 在特定位置插入行
vector<vector<int>> vec2d = {{1,2}, {3,4}};
// 在第一行前面插入新行
vec2d.insert(vec2d.begin(), {5, 6, 7});
// 在第二行前面插入新行
vec2d.insert(vec2d.begin() + 1, {8, 9});
2.3 在特定行添加元素
vector<vector<int>> vec2d = {{1,2}, {3,4}};
vec2d[0].push_back(10); // 第一行末尾添加10 → {1,2,10}
vec2d[1].push_back(20); // 第二行末尾添加20 → {3,4,20}
// 在行内特定位置插入
vec2d[0].insert(vec2d[0].begin() + 1, 15); // 第一行第二个位置插入15 → {1,15,2,10}
3. 访问元素
3.1 使用下标访问
vector<vector<int>> vec2d = {{1,2,3}, {4,5,6}, {7,8,9}};
int element = vec2d[1][2]; // 访问第二行第三列 → 6
vec2d[0][1] = 10; // 修改第一行第二列 → 10
3.2 使用at()访问(更安全,会检查边界)
vector<vector<int>> vec2d = {{1,2,3}, {4,5,6}};
try {
int element = vec2d.at(1).at(2); // 6
vec2d.at(0).at(1) = 10; // 修改元素
} catch (const out_of_range& e) {
cout << "索引越界!" << endl;
}
3.3 遍历二维vector
vector<vector<int>> vec2d = {{1,2,3}, {4,5,6}, {7,8,9}};
// 方法1:使用下标遍历
for (int i = 0; i < vec2d.size(); i++) {
for (int j = 0; j < vec2d[i].size(); j++) {
cout << vec2d[i][j] << " ";
}
cout << endl;
}
// 方法2:使用范围for循环(C++11)
for (const auto& row : vec2d) {
for (int element : row) {
cout << element << " ";
}
cout << endl;
}
// 方法3:使用迭代器
for (auto row_it = vec2d.begin(); row_it != vec2d.end(); row_it++) {
for (auto col_it = row_it->begin(); col_it != row_it->end(); col_it++) {
cout << *col_it << " ";
}
cout << endl;
}
4. 删除元素
4.1 删除行
vector<vector<int>> vec2d = {{1,2}, {3,4}, {5,6}};
vec2d.pop_back(); // 删除最后一行 → 剩下{{1,2}, {3,4}}
vec2d.erase(vec2d.begin()); // 删除第一行 → 剩下{{3,4}}
vec2d.erase(vec2d.begin() + 1, vec2d.end()); // 删除第一行之后的所有行
4.2 删除行内元素
vector<vector<int>> vec2d = {{1,2,3}, {4,5,6}};
vec2d[0].pop_back(); // 删除第一行最后一个元素 → {1,2}
vec2d[1].erase(vec2d[1].begin() + 1); // 删除第二行第二个元素 → {4,6}
4.3 清空
vector<vector<int>> vec2d = {{1,2}, {3,4}};
vec2d.clear(); // 清空所有行
vec2d[0].clear(); // 清空第一行的所有元素
5. 修改大小
5.1 调整行数
vector<vector<int>> vec2d = {{1,2}, {3,4}};
vec2d.resize(5); // 扩展到5行,新行是空的
vec2d.resize(3); // 缩减到3行,多余行被删除
5.2 调整列数
vector<vector<int>> vec2d = {{1,2}, {3,4}};
vec2d[0].resize(5, -1); // 第一行扩展到5列,新元素初始为-1 → {1,2,-1,-1,-1}
vec2d[1].resize(1); // 第二行缩减到1列 → {3}
6. 实用操作
6.1 获取大小信息
vector<vector<int>> vec2d = {{1,2,3}, {4,5}};
int rows = vec2d.size(); // 行数:2
int cols_row0 = vec2d[0].size(); // 第一行的列数:3
bool empty = vec2d.empty(); // 是否为空:false
bool row0_empty = vec2d[0].empty(); // 第一行是否为空:false
6.2 交换
vector<vector<int>> vec1 = {{1,2}, {3,4}};
vector<vector<int>> vec2 = {{5,6,7}, {8,9}};
vec1.swap(vec2); // 交换两个二维vector
swap(vec1[0], vec1[1]); // 交换两行
6.3 判断是否相等
vector<vector<int>> vec1 = {{1,2}, {3,4}};
vector<vector<int>> vec2 = {{1,2}, {3,4}};
if (vec1 == vec2) {
cout << "两个二维vector相等" << endl;
}
7. 分组背包问题的实际应用
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int v, n, t;
cin >> v >> n >> t;
// 定义二维vector存储重量和价值
vector<vector<int>> w(t+1), c(t+1);
// 读取数据并动态添加
for (int i = 0; i < n; i++) {
int weight, value, group;
cin >> weight >> value >> group;
// 动态添加到对应组
w[group].push_back(weight);
c[group].push_back(value);
}
// 使用一维DP数组(推荐用于分组背包)
vector<int> dp(v+1, 0);
// 分组背包核心算法
for (int i = 1; i <= t; i++) {
// 倒序遍历容量,确保每组只选一个
for (int j = v; j >= 0; j--) {
// 遍历当前组的每个物品
for (int k = 0; k < w[i].size(); k++) {
if (j >= w[i][k]) {
dp[j] = max(dp[j], dp[j - w[i][k]] + c[i][k]);
}
}
}
}
cout << dp[v] << endl;
return 0;
}
8. 重要注意事项
-
边界检查 :使用
at()比[]更安全,但性能稍差 -
内存管理:vector会自动管理内存,无需手动释放
-
性能考虑 :如果知道大致大小,使用
reserve()预分配空间 -
不规则二维数组:每行可以有不同数量的元素
这个指南涵盖了二维vector的所有基本操作,掌握了这些就能熟练使用二维vector解决各种问题!