嵌套容器:从零开始的详细教程
本文最后更新于 34 天前,其中的信息可能已经有所发展或是发生改变。

一、为什么要用嵌套容器?(先理解需求)

生活中的例子

想象你需要记录这些东西:

  1. 一个班的成绩表:3个学生,每人有5门课成绩
  2. 一个学校的课程表:5个年级,每个年级有若干班级
  3. 一个城市的电话号码簿:按区号分类,每个区号下有多个号码

这些都需要表格形式多级分类的存储,这时就需要嵌套容器。

二、从简单到复杂

第1步:先复习普通vector

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 1. 普通的一维vector - 存储一组数字
    vector<int> scores = {90, 85, 95, 88};
    
    // 2. 访问单个元素
    cout << "第一个成绩:" << scores[0] << endl;  // 90
    
    // 3. 遍历
    cout << "所有成绩:";
    for (int i = 0; i < scores.size(); i++) {
        cout << scores[i] << " ";
    }
    // 输出:90 85 95 88
}

第2步:思考问题 – 多个学生的成绩

// 假设有3个学生,每个学生有3门课成绩
// 错误做法:用3个独立的vector
vector<int> student1_scores = {90, 85, 88};
vector<int> student2_scores = {78, 92, 85};
vector<int> student3_scores = {88, 79, 94};

// 问题:不好统一管理,不能循环处理所有学生

三、引入二维vector(嵌套vector)

基本概念理解

二维vector就像表格:
┌─────────┬─────────┬─────────┐
│ 学生1   │ 90      │ 85      │ 88      │
├─────────┼─────────┼─────────┤
│ 学生2   │ 78      │ 92      │ 85      │
├─────────┼─────────┼─────────┤
│ 学生3   │ 88      │ 79      │ 94      │
└─────────┴─────────┴─────────┘

在内存中:
outer_vec[0] → {90, 85, 88}  ← 第0行,学生1的成绩
outer_vec[1] → {78, 92, 85}  ← 第1行,学生2的成绩
outer_vec[2] → {88, 79, 94}  ← 第2行,学生3的成绩

第3步:创建二维vector

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 方法1:先创建外层vector,再逐个添加内层vector
    vector<vector<int>> all_students_scores;  // 空的二维vector
    
    // 创建每个学生的成绩vector
    vector<int> student1 = {90, 85, 88};
    vector<int> student2 = {78, 92, 85};
    vector<int> student3 = {88, 79, 94};
    
    // 添加到外层vector
    all_students_scores.push_back(student1);
    all_students_scores.push_back(student2);
    all_students_scores.push_back(student3);
    
    cout << "共有" << all_students_scores.size() << "个学生" << endl;  // 3
    
    // 访问第一个学生的第一门成绩
    cout << "学生1的第1门成绩:" << all_students_scores[0][0] << endl;  // 90
}

第4步:简化创建方法

// 方法2:直接初始化(推荐)
vector<vector<int>> scores = {
    {90, 85, 88},  // 第0个学生的成绩
    {78, 92, 85},  // 第1个学生的成绩
    {88, 79, 94}   // 第2个学生的成绩
};

// 一行代码搞定,清晰直观!

四、如何遍历二维vector?

方法1:双重循环(最容易理解)

vector<vector<int>> scores = {
    {90, 85, 88},
    {78, 92, 85},
    {88, 79, 94}
};

// 外层循环:遍历每个学生
for (int i = 0; i < scores.size(); i++) {
    cout << "学生" << i + 1 << "的成绩:";
    
    // 内层循环:遍历这个学生的每门课
    for (int j = 0; j < scores[i].size(); j++) {
        cout << scores[i][j] << " ";
    }
    cout << endl;
}

输出:

学生1的成绩:90 85 88
学生2的成绩:78 92 85
学生3的成绩:88 79 94

方法2:范围for循环(C++11,更简洁)

int student_num = 1;
for (const vector<int>& student_scores : scores) {  // 遍历每个学生
    cout << "学生" << student_num << "的成绩:";
    
    for (int score : student_scores) {  // 遍历这个学生的成绩
        cout << score << " ";
    }
    cout << endl;
    student_num++;
}

五、理解索引访问

vector<vector<int>> scores = {
    {90, 85, 88},  // scores[0]
    {78, 92, 85},  // scores[1]
    {88, 79, 94}   // scores[2]
};

// 访问方式:scores[行][列]
cout << scores[0][0] << endl;  // 90
cout << scores[1][2] << endl;  // 85
cout << scores[2][1] << endl;  // 79

// 理解:
// scores[0] 获取第一个内层vector {90, 85, 88}
// scores[0][1] 在这个内层vector中取第2个元素 85

六、常见操作

1. 添加新的学生

vector<vector<int>> scores = {
    {90, 85, 88},
    {78, 92, 85}
};

// 添加一个学生
vector<int> new_student = {95, 87, 91};
scores.push_back(new_student);

// 更简洁的写法
scores.push_back({82, 76, 89});  // 直接添加

2. 修改成绩

// 修改第2个学生的第3门成绩
scores[1][2] = 90;  // 原来是85,改为90

// 添加一门新课的成绩(给所有学生)
for (int i = 0; i < scores.size(); i++) {
    scores[i].push_back(80 + i * 5);  // 假设新成绩
}

3. 删除学生

// 删除第2个学生(索引1)
scores.erase(scores.begin() + 1);

// 删除第一个学生的第2门成绩
scores[0].erase(scores[0].begin() + 1);

七、不同形状的二维vector

重要特点:每行的长度可以不同!

// 不规则二维数组 - 每个学生课程数不同
vector<vector<int>> irregular_scores = {
    {90, 85, 88, 92},    // 学生1有4门课
    {78, 92},            // 学生2有2门课
    {88, 79, 94, 87, 91} // 学生3有5门课
};

// 查看每个学生有多少门课
for (int i = 0; i < irregular_scores.size(); i++) {
    cout << "学生" << i+1 << "有" << irregular_scores[i].size() 
         << "门课" << endl;
}

八、实际案例:成绩统计系统

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    // 学生姓名和成绩
    vector<string> names = {"张三", "李四", "王五"};
    
    // 每个学生的成绩(三门课)
    vector<vector<int>> scores = {
        {90, 85, 88},  // 张三的成绩
        {78, 92, 85},  // 李四的成绩
        {88, 79, 94}   // 王五的成绩
    };
    
    // 计算每个学生的平均分
    cout << "====== 学生成绩统计 ======\n";
    for (int i = 0; i < names.size(); i++) {
        cout << names[i] << "的成绩:";
        
        int sum = 0;
        for (int j = 0; j < scores[i].size(); j++) {
            cout << scores[i][j] << " ";
            sum += scores[i][j];
        }
        
        double average = static_cast<double>(sum) / scores[i].size();
        cout << " 平均分:" << average << endl;
    }
}

九、三维vector(了解)

// 理解三维:多个班级,每个班级有多个学生,每个学生有多门成绩
vector<vector<vector<int>>> all_classes_scores = {
    // 班级1
    {
        {90, 85, 88},  // 学生1
        {78, 92, 85}   // 学生2
    },
    // 班级2
    {
        {88, 79, 94},  // 学生1
        {76, 85, 89},  // 学生2
        {92, 88, 90}    // 学生3
    }
};

// 访问:班级[学生][课程]
cout << "班级1,学生2,第3门成绩:" 
     << all_classes_scores[0][1][2] << endl;  // 85

十、总结和练习

关键点总结

  1. 嵌套vector​ = vector里面存放vector
  2. 语法vector<vector<类型>> 变量名
  3. 访问变量名[行][列]
  4. 每行长度可以不同,这是与二维数组的最大区别
  5. 遍历:用双重循环

练习题

  1. 创建一个3×3的矩阵,并初始化为:
1 2 3
4 5 6
7 8 9

然后计算对角线元素的和。

  1. 创建一个记录5个学生考试成绩的二维vector,每个学生参加考试的科目数不同,然后计算每个学生的总分。
  2. 创建一个三角形的数字金字塔,使用嵌套vector存储:
1
2 3
4 5 6
7 8 9 10

参考答案

// 练习1
vector<vector<int>> matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
int sum = matrix[0][0] + matrix[1][1] + matrix[2][2];
cout << "对角线之和:" << sum << endl;  // 15

记住:从一维到二维,就是把每个元素从单个值变成了一组值。多练习几次,就会很自然了!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇