跳转至

C++ 编程入门 - Day 3

引言

在今天的学习中,我们将深入探索 C++ 标准库中的 <vector> 头文件。Vector 是 C++ 中最常用的容器之一,它提供了动态数组的功能,使我们能够更灵活地处理数据集合。


1. <vector> 详细介绍

<vector> 是 C++ 标准库中提供的动态数组容器。它是一个模板类,可以存储任意类型的数据。与传统的数组相比,vector 提供了更多的功能和安全性。

vector 的特点:

  • 动态大小:可以自动调整大小以容纳更多元素
  • 随机访问:可以通过索引直接访问任何元素
  • 内存管理:自动管理内存,避免了手动分配和释放内存的麻烦
  • 丰富的成员函数:提供了大量的成员函数,用于操作容器
  • 迭代器支持:支持所有类型的迭代器操作

基本操作:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    // 向量初始化
    vector<int> vec1; // 空向量
    vector<int> vec2(5); // 包含 5 个默认值(0)的向量
    vector<int> vec3(5, 2); // 包含 5 个值为 2 的向量
    vector<int> vec4 = {1, 2, 3, 4, 5}; // 使用初始化列表

    // 输出向量大小
    cout << "vec1 size: " << vec1.size() << endl;
    cout << "vec2 size: " << vec2.size() << endl;
    cout << "vec3 size: " << vec3.size() << endl;
    cout << "vec4 size: " << vec4.size() << endl;

    // 访问元素
    cout << "vec4[2]: " << vec4[2] << endl;
    cout << "vec4.at(2): " << vec4.at(2) << endl;

    // 添加元素
    vec1.push_back(10);
    vec1.push_back(20);
    vec1.push_back(30);

    cout << "vec1 after push_back: ";
    for (int i : vec1) {
        cout << i << " ";
    }
    cout << endl;

    // 删除元素
    vec1.pop_back();
    cout << "vec1 after pop_back: ";
    for (int i : vec1) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

2. 经典示例

示例 1:向量作为动态数组

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> numbers;
    int num;

    cout << "Enter numbers (enter -1 to stop): " << endl;

    while (cin >> num && num != -1) {
        numbers.push_back(num);
    }

    cout << "You entered: ";
    for (int n : numbers) {
        cout << n << " ";
    }
    cout << endl;

    // 计算总和
    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    cout << "Sum: " << sum << endl;

    // 计算平均值
    double average = static_cast<double>(sum) / numbers.size();
    cout << "Average: " << average << endl;

    return 0;
}

示例 2:二维向量

#include <iostream>
#include <vector>

using namespace std;

int main() {
    // 创建一个 3x3 的二维向量
    vector<vector<int>> matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    cout << "Matrix:" << endl;
    for (const auto& row : matrix) {
        for (int num : row) {
            cout << num << " ";
        }
        cout << endl;
    }

    // 访问元素
    cout << "Element at (1,1): " << matrix[1][1] << endl;

    // 添加一行
    matrix.push_back({10, 11, 12});
    cout << "After adding a row:" << endl;
    for (const auto& row : matrix) {
        for (int num : row) {
            cout << num << " ";
        }
        cout << endl;
    }

    return 0;
}

示例 3:向量与算法结合

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> numbers = {5, 2, 8, 1, 9, 3};

    // 排序
    sort(numbers.begin(), numbers.end());
    cout << "Sorted numbers: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    // 反转
    reverse(numbers.begin(), numbers.end());
    cout << "Reversed numbers: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    // 查找
    int target = 8;
    auto it = find(numbers.begin(), numbers.end(), target);

    if (it != numbers.end()) {
        cout << "Found " << target << " at index " << distance(numbers.begin(), it) << endl;
    } else {
        cout << "Did not find " << target << endl;
    }

    return 0;
}

3. 常见的问题和回答

问题 1:如何在向量中间插入元素?

可以使用 insert() 成员函数:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

    // 在索引位置 2 插入值为 10 的元素
    numbers.insert(numbers.begin() + 2, 10);

    cout << "After insertion: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

问题 2:如何删除向量中的元素?

可以使用 erase() 成员函数:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

    // 删除索引位置为 2 的元素
    numbers.erase(numbers.begin() + 2);

    cout << "After erasure: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

问题 3:如何避免向量的频繁重新分配?

可以使用 reserve() 成员函数预先分配内存,避免频繁的内存重新分配:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> numbers;
    numbers.reserve(1000); // 预先分配 1000 个元素的空间

    for (int i = 0; i < 1000; i++) {
        numbers.push_back(i);
    }

    cout << "Size: " << numbers.size() << endl;
    cout << "Capacity: " << numbers.capacity() << endl;

    return 0;
}

总结

在今天的学习中,我们深入探索了 C++ 标准库中的 <vector> 头文件和 std::vector 类。我们学习了:

  1. std::vector 的基本概念和特点
  2. 向量的初始化和基本操作
  3. 三个经典示例:动态数组、二维向量和与算法结合
  4. 常见问题的解答,包括插入、删除元素和内存管理

std::vector 是 C++ 编程中非常重要的容器,掌握好向量操作将使您的程序更加高效和灵活。


练习建议: 1. 实现一个简单的待办事项列表,使用向量存储任务 2. 编写一个程序,计算向量中偶数和奇数的数量 3. 实现一个函数,合并两个已排序的向量