C++中vector类型的先容和使用

[复制链接]
发表于 2025-6-10 23:21:48 | 显示全部楼层 |阅读模式
一、vector 类型的简介

  vector 是 C++ 标准模板库(STL)中最常用的顺序容器之一,底层实现为 动态数组。它提供动态增长、随机访问、高效末尾插入等特性。
1.1 基本先容

  1. #include <vector>
  2. std::vector<int> numbers;
复制代码

1.2 常见用法示例

初始化方式
  1. std::vector<int> v1;                     // 空向量
  2. std::vector<int> v2(5);                  // 5个默认值(0)
  3. std::vector<int> v3(5, 42);              // 5个 42
  4. std::vector<int> v4 = {1, 2, 3, 4};      // 列表初始化
复制代码
常用操纵
  1. v1.push_back(10);       // 尾部添加元素
  2. v1.pop_back();          // 删除最后一个元素
  3. v1.size();              // 元素数量
  4. v1.empty();             // 是否为空
  5. v1.clear();             // 清空所有元素
  6. v1.at(2);               // 安全访问第3个元素(带边界检查)
  7. v1[2];                  // 快速访问第3个元素(无检查)
复制代码
遍历方式
  1. for (size_t i = 0; i < v1.size(); ++i)
  2.     std::cout << v1[i] << std::endl;
  3. for (int x : v1)        // C++11 范围循环
  4.     std::cout << x << std::endl;
复制代码
1.3 常见成员函数简表


二、vector 数据的插入

  std::vector 提供多种方式将数据插入容器中,适用于不同的使用场景(如单个元素插入、批量插入、自定义位置插入等)。
2.1 push_back() —— 在尾部插入一个元素

特点:时间复杂度均派为 O(1)
示例:
  1. std::vector<int> v;
  2. v.push_back(10);
  3. v.push_back(20);  // v = {10, 20}
复制代码
2.2 emplace_back() —— 在尾部“就地”构造对象

特点:
   

  • 避免临时对象拷贝或移动
  • 构造更复杂类型推荐使用
  示例:
  1. std::vector<std::pair<int, std::string>> v;
  2. v.emplace_back(1, "Alice");  // 直接构造 pair(1, "Alice")
复制代码
2.3 insert() —— 在任意位置插入一个或多个元素

重载形式包括:
插入单个元素
  1. std::vector<int> v = {1, 2, 4};
  2. v.insert(v.begin() + 2, 3);  // v = {1, 2, 3, 4}
复制代码
插入多个雷同元素
  1. v.insert(v.begin(), 3, 100);  // 插入3个100在开头
复制代码
插入另一 vector 的一段范围
  1. std::vector<int> v1 = {1, 2};
  2. std::vector<int> v2 = {10, 20, 30};
  3. v1.insert(v1.end(), v2.begin(), v2.end());  // v1 = {1, 2, 10, 20, 30}
复制代码
2.4 emplace() —— 在任意位置就地构造对象

雷同于 insert(),但对象是“就地构造”而非拷贝。
示例:
  1. std::vector<std::pair<int, std::string>> v;
  2. v.emplace(v.begin(), 1, "Bob");  // 插入 pair(1, "Bob") 到开头
复制代码
2.5 assign() —— 更换整个 vector 的内容

注意这是更换整个内容,不是插入。
  1. std::vector<int> v;
  2. v.assign(5, 42);  // v = {42, 42, 42, 42, 42}
复制代码
插入方式对比表

三、vector 数据的遍历

3.1 范围-based for 循环(C++11 起)

  1. #include <vector>
  2. #include <iostream>
  3. std::vector<int> vec = {1, 2, 3, 4, 5};
  4. for (int value : vec) {
  5.     std::cout << value << " ";
  6. }
复制代码
3.2 使用下标访问

  1. for (size_t i = 0; i < vec.size(); ++i) {
  2.     std::cout << vec[i] << " ";
  3. }
复制代码
也可以用 at() 提供边界查抄:
  1. for (size_t i = 0; i < vec.size(); ++i) {
  2.     std::cout << vec.at(i) << " ";
  3. }
复制代码
3.3 使用迭代器

  1. for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
  2.     std::cout << *it << " ";
  3. }
复制代码
假如不需要修改数据,可使用 const_iterator:
  1. for (std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) {
  2.     std::cout << *it << " ";
  3. }
复制代码
3.4 使用 std::for_each 和 Lambda(C++11 起)

  1. #include <algorithm>
  2. std::for_each(vec.begin(), vec.end(), [](int value) {
  3.     std::cout << value << " ";
  4. });
复制代码
四、vector 数据的删除

4.1 删除尾部元素:pop_back()

  1. std::vector<int> vec = {1, 2, 3};
  2. vec.pop_back(); // 删除最后一个元素(3)
复制代码
4.2 按下标删除一个元素:erase(iterator)

  1. std::vector<int> vec = {10, 20, 30, 40};
  2. vec.erase(vec.begin() + 2); // 删除索引为2的元素(30)
复制代码
4.3 删除一个区间:erase(begin, end)

  1. std::vector<int> vec = {1, 2, 3, 4, 5};
  2. vec.erase(vec.begin() + 1, vec.begin() + 4); // 删除 2, 3, 4
  3. // 结果为 vec = {1, 5}
复制代码
4.4 按值删除(配合 remove)

  1. #include <algorithm>
  2. std::vector<int> vec = {1, 2, 3, 2, 4};
  3. // 删除所有值为 2 的元素
  4. vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
  5. // 结果为 vec = {1, 3, 4}
复制代码
注意:std::remove 不是真正删除,而是将不符合条件的元素移到后面,返回“新逻辑末尾”,再用 erase 删除尾部的冗余数据。
4.5 按条件删除(用 lambda)

  1. // 删除所有大于3的元素
  2. vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) {
  3.     return x > 3;
  4. }), vec.end());
复制代码
4.6 清空整个 vector:clear()

  1. vec.clear(); // 删除所有元素,size() 为 0
复制代码
4.7 删除自定义类型的元素(按值或条件)

  1. struct Person {
  2.     std::string name;
  3.     int age;
  4. };
  5. std::vector<Person> people = {
  6.     {"Alice", 25}, {"Bob", 30}, {"Charlie", 25}
  7. };
  8. // 删除所有 age 为 25 的人
  9. people.erase(std::remove_if(people.begin(), people.end(), [](const Person& p) {
  10.     return p.age == 25;
  11. }), people.end());
复制代码
4.8 删除某个元素再次遍历

方法 1:使用 erase + iterator,精确方式如下:
  1. #include <vector>
  2. #include <iostream>
  3. int main() {
  4.     std::vector<int> vec = {1, 2, 3, 2, 4};
  5.     for (auto it = vec.begin(); it != vec.end(); ) {
  6.         if (*it == 2) {
  7.             it = vec.erase(it);  // erase 返回新的 iterator,指向被删元素的下一个位置
  8.         } else {
  9.             ++it;
  10.         }
  11.     }
  12.     // 再次遍历
  13.     for (int val : vec) {
  14.         std::cout << val << " ";
  15.     }
  16.     return 0;
  17. }
复制代码
方法 2:先删除,再单独遍历(更清晰):
  1. vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
  2. // 再次遍历
  3. for (int val : vec) {
  4.     std::cout << val << " ";
  5. }
复制代码
错误示例(不要这样做):
  1. for (auto it = vec.begin(); it != vec.end(); ++it) {
  2.     if (*it == 2) {
  3.         vec.erase(it); // ❌ it 会失效,下一次 ++it 就是未定义行为
  4.     }
  5. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表