基本用法
vector定义在<vector>头文件中,需包含后使用
c++
#include <vector>
- 初始化
c++
// 1、空构造函数,构造一个空的vector
vector<int> v1;
cout << v1.size() << " " << v1.capacity() << endl;
// 2、指定大小,默认初始化(int默认0,string默认空)
vector<int> v2(10);
cout << v2.size() << " " << v2.capacity() << v2.at(0) << endl;
// 指定大小、指定初始化值
vector<int> v3(10, 5);
cout << v3.size() << " " << v3.capacity() << v3.at(0) << endl;
// 3、拷贝构造,从其他对象构造一个
vector<int> v4(v3);
cout << v4.size() << " " << v4.capacity() << v4.at(0) << endl;
// 4、列表初始化
vector<int> v5 = { 0, 1, 2, 3, 4, 5 };
cout << v5.size() << " " << v5.capacity() << v5.at(2) << endl;
// 5、迭代器范围初始化
vector<int> v6(v5.begin() + 1, v5.end() - 1 );
cout << v6.size() << " " << v6.capacity() << v6.at(2) << endl;
- 元素访问
- 下标访问[](无越界检查)
c++
vector<int> vt = { 1, 2, 3, 4, 5 };
// 1、下标访问
cout << vt[1] << endl;
// 越界访问,程序中断
cout << vt[10] << endl;
- at()访问(有越界检查,抛异常out_of_range)
c++
vector<int> vt = { 1, 2, 3, 4, 5 };
// 2、at()访问
cout << vt.at(2) << endl;
// 越界访问,抛出异常
cout << vt.at(10) << endl;
- front() / back() 访问首尾元素
c++
vector<int> vt = { 1, 2, 3, 4, 5 };
// 3、访问首尾元素
cout << vt.front() << " " << vt.back() << endl;
- 迭代器访问(遍历专用)
c++
vector<int> vt = { 1, 2, 3, 4, 5 };
// 4、迭代器访问
for (vector<int>::iterator begin = vt.begin(); begin < vt.end(); ++begin)
{
cout << *begin << endl;
}
核心操作方法
增删元素
- 尾部增删(推荐,效率高)
push_back(val)尾部添加元素emplace_back(val):C++11 新增,直接在尾部构造元素(避免拷贝,效率更高);pop_back():删除尾部元素(无返回值)。
c++
vector<int> vt;
// 尾部添加元素
vt.push_back(1);
// 尾部构造
vt.emplace_back(2);
// 尾部删除
vt.pop_back()
- 指定位置增删
insert(pos, val):在迭代器pos处插入元素,返回新元素的迭代器;emplace(pos, val):C++11 新增,在pos处构造元素;erase(pos):删除pos处的元素,返回下一个有效迭代器;erase(begin, end):删除区间内的元素。
c++
vector<int> vt = {1, 3 ,5};
// 1、insert插入元素
vector<int>::iterator begin = vt.begin();
vt.insert(begin + 1, 2);
// 2、emplace在指定pos出构造元素
begin = vt.begin();
vt.emplace(begin + 3, 4);
// 3、删除指定位置的元素,返回下一个有效迭代器
// end迭代器返回的是末尾元素的下一位置迭代器,因此-1
vector<int>::iterator rs = vt.erase(vt.end()-1);
//cout << *rs << endl;
// 4、删除区间
vt.erase(vt.begin(), vt.begin() + 2);
for (vector<int>::iterator begin = vt.begin(); begin != vt.end(); ++begin)
{
cout << *begin << endl;
}
- 清空与重置
clear():清空所有元素(size变为 0,capacity不变);resize(n):调整size为 n,不足补默认值,超出则截断;assign(n, val):清空原有元素,重新赋值 n 个 val;swap(v2):与另一个 vector 交换数据(O (1) 效率)。
c++
vector<int> vt = {1, 3 ,5};
vt.clear();
容量与大小管理
size()返回当前元素个数(实际存储的元素数) capacity()返回当前分配的内存可容纳的元素数(不含额外空间) empty()判断是否为空(size==0 时返回 true) reserve(n)预分配至少 n 个元素的内存(仅扩容 capacity,不改变 size)
vector性能优化
- 减少扩容次数,扩容会触发"分配新内存-拷贝元素-释放原内存"的过程,耗费时间且会导致迭代器失效问题。优化方法:提前使用reserve预分配足够的内存。
- 使用emplace_back替代push_back,push_back 会先构造临时对象,再拷贝到容器;emplace_back 直接在容器内存中构造对象,减少拷贝:
- 批量操作替代单次操作,如在插入和删除多个元素时,优先使用区间操作。
避坑点
- 迭代器失效
- 扩容后,所有的迭代器、指针、引用失效
- 插入元素,插入位置后的迭代器失效
- 删除元素,删除位置后的迭代器失效 避坑方法:修改容器后,重新获取迭代器。
- size和capacity要分清,size是实际元素个数,capacity是已分配内存可容纳的元素个数;
- 空vector的访问,空 vector 的 begin() == end(),front()/back()/at(0) 均会导致未定义行为。