在 C++ 的标准模板库(STL)中,vector是一个十分强大且常用的容器,它类似于动态数组,能够根据需要自动调整大小,为开发者提供了高效、便捷的数据存储和操作方式。无论是在日常编程还是算法竞赛中,vector都发挥着重要作用。接下来,我们就深入探讨一下vector的详细用法。
一、vector 的概念与头文件引入
vector是一个模板类,它能够存储各种类型的数据,包括内置类型(如int、double等)和自定义类型(如结构体、类对象)。与普通数组相比,vector的优势在于其大小可以动态变化,在插入或删除元素时,它会自动管理内存,无需手动分配和释放。
在使用vector之前,需要引入相应的头文件:
#include <vector>
同时,为了方便使用,通常会使用using指令引入std命名空间:
using namespace std;
二、vector 的创建
2.1 创建空的 vector
vector<int> v1; // 创建一个空的vector,用于存储int类型的数据
vector<string> v2; // 创建一个空的vector,用于存储string类型的数据
2.2 创建指定大小的 vector
vector<int> v3(10); // 创建一个包含10个int元素的vector,每个元素默认初始化为0
vector<double> v4(5, 3.14); // 创建一个包含5个double元素的vector,每个元素初始化为3.14
2.3 通过拷贝构造函数创建 vector
vector<int> v5 = {1, 2, 3, 4, 5};
vector<int> v6(v5); // 通过拷贝v5创建v6,v6和v5内容相同
2.4 使用初始化列表创建 vector
vector<int> v7 = {10, 20, 30, 40}; // 使用初始化列表直接初始化vector
三、vector 元素的访问
3.1 通过下标访问
vector<int> v = {1, 2, 3, 4, 5};
cout << v[0] << endl; // 输出第一个元素,结果为1
v[2] = 10; // 修改第三个元素的值为10
需要注意的是,使用下标访问时不会进行越界检查,如果访问越界,会导致未定义行为。
3.2 使用 at () 函数访问
vector<int> v = {1, 2, 3, 4, 5};
cout << v.at(0) << endl; // 输出第一个元素,结果为1
try {
v.at(10); // 尝试访问越界元素,会抛出out_of_range异常
} catch (const out_of_range& e) {
cerr << "Out of range error: " << e.what() << endl;
}
at()函数会进行越界检查,当访问越界时会抛出out_of_range异常,因此在不确定下标是否合法时,使用at()函数更加安全。
3.3 使用迭代器访问
vector<int> v = {1, 2, 3, 4, 5};
vector<int>::iterator it;
for (it = v.begin(); it != v.end(); ++it) {
cout << *it << " "; // 输出vector中的每个元素
}
cout << endl;
begin()函数返回指向第一个元素的迭代器,end()函数返回指向最后一个元素之后的迭代器。通过迭代器可以方便地遍历vector中的元素。此外,还可以使用auto关键字简化迭代器的声明:
vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl;
四、vector 元素的插入
4.1 在末尾插入元素
vector<int> v;
v.push_back(1); // 在vector末尾插入元素1
v.push_back(2); // 在vector末尾插入元素2
push_back()函数会将元素添加到vector的末尾,如果vector的内存不足,它会自动重新分配更大的内存空间。
4.2 在指定位置插入元素
vector<int> v = {1, 2, 3};
v.insert(v.begin() + 1, 10); // 在第二个元素位置插入10,此时vector变为{1, 10, 2, 3}
v.insert(v.begin(), 2, 5); // 在开头插入两个5,此时vector变为{5, 5, 1, 10, 2, 3}
insert()函数可以在指定位置插入一个或多个元素,第一个参数是迭代器,指定插入位置,第二个参数是要插入的元素,第三个参数(可选)是要插入元素的个数。
五、vector 元素的删除
5.1 删除末尾元素
vector<int> v = {1, 2, 3, 4, 5};
v.pop_back(); // 删除末尾元素,此时vector变为{1, 2, 3, 4}
pop_back()函数会删除vector的最后一个元素。
5.2 删除指定位置的元素
vector<int> v = {1, 2, 3, 4, 5};
v.erase(v.begin() + 2); // 删除第三个元素,此时vector变为{1, 2, 4, 5}
v.erase(v.begin(), v.begin() + 2); // 删除前两个元素,此时vector变为{4, 5}
erase()函数可以删除指定位置的单个元素或一段连续的元素,第一个参数是指向要删除元素或区间起始位置的迭代器,第二个参数(可选)是指向区间末尾位置的迭代器。
六、vector 的其他常用操作
6.1 获取 vector 的大小
vector<int> v = {1, 2, 3, 4, 5};
int size = v.size(); // 获取vector中元素的个数,size的值为5
size()函数返回vector中当前存储的元素个数。
6.2 判断 vector 是否为空
vector<int> v;
if (v.empty()) {
cout << "vector is empty" << endl;
}
empty()函数用于判断vector是否为空,如果为空则返回true,否则返回false。
6.3 交换两个 vector 的内容
vector<int> v1 = {1, 2, 3};
vector<int> v2 = {4, 5, 6};
v1.swap(v2); // 交换v1和v2的内容,此时v1变为{4, 5, 6},v2变为{1, 2, 3}
swap()函数可以交换两个vector的所有元素。
6.4 调整 vector 的大小
vector<int> v = {1, 2, 3};
v.resize(5); // 将vector的大小调整为5,新增的两个元素默认初始化为0
v.resize(2); // 将vector的大小调整为2,删除后面多余的元素
resize()函数可以改变vector的大小,如果新大小大于原大小,会在末尾添加默认初始化的元素;如果新大小小于原大小,会删除末尾多余的元素。
七、vector 与自定义类型
vector不仅可以存储内置类型,还可以存储自定义类型,如结构体和类对象。
struct Point {
int x;
int y;
Point(int a, int b) : x(a), y(b) {}
};
vector<Point> points;
points.push_back(Point(1, 2));
points.push_back(Point(3, 4));
for (const auto& p : points) {
cout << "(" << p.x << ", " << p.y << ")" << endl;
}
在使用自定义类型时,需要确保该类型定义了合适的构造函数、拷贝构造函数等必要的成员函数,以保证vector能够正确地存储和操作这些对象。
以上就是 C++ 中vector的详细用法。如果你还想了解vector在特定场景下的应用,或是对其他 STL 容器感兴趣,欢迎在评论区留言交流。