C++中vector类型的介绍和使用
文章目录
- 一、vector 类型的简介
- 1.1 基本介绍
- 1.2 常见用法示例
- 1.3 常见成员函数简表
- 二、vector 数据的插入
- 2.1 push_back() —— 在尾部插入一个元素
- 2.2 emplace_back() —— 在尾部“就地”构造对象
- 2.3 insert() —— 在任意位置插入一个或多个元素
- 2.4 emplace() —— 在任意位置就地构造对象
- 2.5 assign() —— 替换整个 vector 的内容
- 三、vector 数据的遍历
- 3.1 范围-based for 循环(C++11 起)
- 3.2 使用下标访问
- 3.3 使用迭代器
- 3.4 使用 std::for_each 和 Lambda(C++11 起)
- 四、vector 数据的删除
- 4.1 删除尾部元素:pop_back()
- 4.2 按下标删除一个元素:erase(iterator)
- 4.3 删除一个区间:erase(begin, end)
- 4.4 按值删除(配合 remove)
- 4.5 按条件删除(用 lambda)
- 4.6 清空整个 vector:clear()
- 4.7 删除自定义类型的元素(按值或条件)
- 4.8 删除某个元素再次遍历
一、vector 类型的简介
vector 是 C++ 标准模板库(STL)中最常用的顺序容器之一,底层实现为 动态数组。它提供动态增长、随机访问、高效末尾插入等特性。
1.1 基本介绍
#include <vector>
std::vector<int> numbers;
1.2 常见用法示例
初始化方式
std::vector<int> v1; // 空向量
std::vector<int> v2(5); // 5个默认值(0)
std::vector<int> v3(5, 42); // 5个 42
std::vector<int> v4 = {1, 2, 3, 4}; // 列表初始化
常用操作
v1.push_back(10); // 尾部添加元素
v1.pop_back(); // 删除最后一个元素
v1.size(); // 元素数量
v1.empty(); // 是否为空
v1.clear(); // 清空所有元素
v1.at(2); // 安全访问第3个元素(带边界检查)
v1[2]; // 快速访问第3个元素(无检查)
遍历方式
for (size_t i = 0; i < v1.size(); ++i)std::cout << v1[i] << std::endl;for (int x : v1) // C++11 范围循环std::cout << x << std::endl;
1.3 常见成员函数简表
二、vector 数据的插入
std::vector 提供多种方式将数据插入容器中,适用于不同的使用场景(如单个元素插入、批量插入、自定义位置插入等)。
2.1 push_back() —— 在尾部插入一个元素
特点:时间复杂度均摊为 O(1)
示例:
std::vector<int> v;
v.push_back(10);
v.push_back(20); // v = {10, 20}
2.2 emplace_back() —— 在尾部“就地”构造对象
特点:
- 避免临时对象拷贝或移动
- 构造更复杂类型推荐使用
示例:
std::vector<std::pair<int, std::string>> v;
v.emplace_back(1, "Alice"); // 直接构造 pair(1, "Alice")
2.3 insert() —— 在任意位置插入一个或多个元素
重载形式包括:
插入单个元素
std::vector<int> v = {1, 2, 4};
v.insert(v.begin() + 2, 3); // v = {1, 2, 3, 4}
插入多个相同元素
v.insert(v.begin(), 3, 100); // 插入3个100在开头
插入另一 vector 的一段范围
std::vector<int> v1 = {1, 2};
std::vector<int> v2 = {10, 20, 30};
v1.insert(v1.end(), v2.begin(), v2.end()); // v1 = {1, 2, 10, 20, 30}
2.4 emplace() —— 在任意位置就地构造对象
类似于 insert(),但对象是“就地构造”而非拷贝。
示例:
std::vector<std::pair<int, std::string>> v;
v.emplace(v.begin(), 1, "Bob"); // 插入 pair(1, "Bob") 到开头
2.5 assign() —— 替换整个 vector 的内容
注意这是替换整个内容,不是插入。
std::vector<int> v;
v.assign(5, 42); // v = {42, 42, 42, 42, 42}
插入方式对比表
三、vector 数据的遍历
3.1 范围-based for 循环(C++11 起)
#include <vector>
#include <iostream>std::vector<int> vec = {1, 2, 3, 4, 5};for (int value : vec) {std::cout << value << " ";
}
3.2 使用下标访问
for (size_t i = 0; i < vec.size(); ++i) {std::cout << vec[i] << " ";
}
也可以用 at() 提供边界检查:
for (size_t i = 0; i < vec.size(); ++i) {std::cout << vec.at(i) << " ";
}
3.3 使用迭代器
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";
}
如果不需要修改数据,可使用 const_iterator:
for (std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) {std::cout << *it << " ";
}
3.4 使用 std::for_each 和 Lambda(C++11 起)
#include <algorithm>std::for_each(vec.begin(), vec.end(), [](int value) {std::cout << value << " ";
});
四、vector 数据的删除
4.1 删除尾部元素:pop_back()
std::vector<int> vec = {1, 2, 3};
vec.pop_back(); // 删除最后一个元素(3)
4.2 按下标删除一个元素:erase(iterator)
std::vector<int> vec = {10, 20, 30, 40};
vec.erase(vec.begin() + 2); // 删除索引为2的元素(30)
4.3 删除一个区间:erase(begin, end)
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.erase(vec.begin() + 1, vec.begin() + 4); // 删除 2, 3, 4
// 结果为 vec = {1, 5}
4.4 按值删除(配合 remove)
#include <algorithm>std::vector<int> vec = {1, 2, 3, 2, 4};
// 删除所有值为 2 的元素
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());
// 结果为 vec = {1, 3, 4}
注意:std::remove 不是真正删除,而是将不符合条件的元素移到后面,返回“新逻辑末尾”,再用 erase 删除尾部的冗余数据。
4.5 按条件删除(用 lambda)
// 删除所有大于3的元素
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) {return x > 3;
}), vec.end());
4.6 清空整个 vector:clear()
vec.clear(); // 删除所有元素,size() 为 0
4.7 删除自定义类型的元素(按值或条件)
struct Person {std::string name;int age;
};std::vector<Person> people = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 25}
};// 删除所有 age 为 25 的人
people.erase(std::remove_if(people.begin(), people.end(), [](const Person& p) {return p.age == 25;
}), people.end());
4.8 删除某个元素再次遍历
方法 1:使用 erase + iterator,正确方式如下:
#include <vector>
#include <iostream>int main() {std::vector<int> vec = {1, 2, 3, 2, 4};for (auto it = vec.begin(); it != vec.end(); ) {if (*it == 2) {it = vec.erase(it); // erase 返回新的 iterator,指向被删元素的下一个位置} else {++it;}}// 再次遍历for (int val : vec) {std::cout << val << " ";}return 0;
}
方法 2:先删除,再单独遍历(更清晰):
vec.erase(std::remove(vec.begin(), vec.end(), 2), vec.end());// 再次遍历
for (int val : vec) {std::cout << val << " ";
}
错误示例(不要这样做):
for (auto it = vec.begin(); it != vec.end(); ++it) {if (*it == 2) {vec.erase(it); // ❌ it 会失效,下一次 ++it 就是未定义行为}
}