vector (向量)概念
- vector 是将元素置于一个动态数组中加以管理的容器
- 可以随机存储元素, 支持索引值直接存取( []操作符 或 at()方法 )
- 由于在中部插入或删除元素需要将其他元素前移或者后移, 因此在中部或头部插入元素或移除元素比较费时, 在尾部添加或移除元素非常快速
vector 对象的构造
// vector 包含在头文件 <vector> 中
#include <vector>
#include <iostream>
using namespace std;
// 创建对象时, 调用 vector 的默认构造函数
// 由于内部实现采用了函数模版来实现, 所以采用与函数模版一致的方式(vector<类型>)来指定容器中存放的元素
vector<int> v1;
vector<float> v2;
// 当使用 vector 的默认构造函数后, 不能直接直接通过下标去赋值
// v1[0] = 1; // 错误, 原因: 还未分配空间
cout << "v1 容器的元素个数: " << v1.size() << endl;
cout << "v1 容器的大小: " << v1.capacity() << endl;
// vector 中元素个数与容量是不一定相等的, 元素个数 <= 容量, 具体关系由内部算法实现
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
cout << "插入 3 个元素后:" << endl;
cout << "v1 容器的元素个数: " << v1.size() << endl;
cout << "v1 容器的大小: " << v1.capacity() << endl;
// vector 带参数的构造函数
// vector<int> v3(10); // 构造时就分配空间, 同时插入元素, 元素默认均为 0
// vector<int> v4(10, 8); // 初始元素指定为 8
// vector<int> v5(v4); // 调用拷贝构造函数
// vector<int> v6(v5.begin()+1, v5.end()) // 从第二个开始拷贝, 到最后一个结束(也可以放入数组的指针进行拷贝构造)
// 最后一种情况需要注意, 由于.end()指向的是最后一个元素的后一个位置, 所以会包含最后一个元素
// 但如果采用数组指针, 则是"左闭右开", 右侧不包含指针指向的那个元素, 与 python 中数组切片时的情况相似
vector 的赋值
// 方法1
vector<int> v(10);
v[0] = 1;
v[1] = 2;
// 方法2
// .assign() 也可以采用指针(迭代器||数组指针)进行赋值, 与构造时原则相同
v.assign(2, 88); // .assign() 方法不管原本容器中的元素个数, 将元素个数重新定义为 2, 并都赋值为 88
cout << "v 容器的元素个数: " << v.size() << endl;
vector 的大小
vector在扩容时, 如果没有更长的连续空间, vector会重新寻找新的更长内存位置, 将原有元素拷贝过去进行扩容, 效率不高, 因此在使用时最好先预估会存放多少元素, 申请相应元素个数的空间后再操作
.empty()
可以用于判断vector是否为空, 为空返回 true, 反之返回 false
.resize(int a)
可以将vector中元素个数缩小为括号内指定的个数 a , 后面多余的元素会被抹去, 但是总容量不变
.resize(int a, <type> b)
可以将vector中元素个数扩充为括号内指定的个数 a , 新增的元素指定为 b, 若不指定默认为 0
在尾部添加和删除元素
.push_back()
可以用于在尾部添加元素
vector<int> v(10);
v.push_back(1); // 在尾部添加一个元素
v.pop_back(); // 在尾部删除一个元素, 不返回任何值
// .push_back(int &&_val) - 右值引用 c++11新特性 后续再学习
输出元素
通用方法:
-
for 循环 + []索引
-
for 循环 + .at()方法
特殊位置元素:
- .front() 返回第一个元素的引用, 可以直接修改 vector 中的值
- .back() 返回最后一个元素的引用, 可以直接修改 vector 中的值
逆向输出:
vector<int>::reverse_iterator rit = v.rbegin();
for (; rit != v.rend(); rit++) { // rbegin()的位置就是最后一个元素的位置, rend()的位置就是第一个元素前一个的位置
cout << *rit << endl;
}
插入元素
vector<int> v(10, 1);
vector<int> v_(2, 2);
// 第一个参数为迭代器, 第二个位置为要插入的元素
v.insert(v.begin()+1, 8); // 在第二个元素的位置插入一个 8, 返回新数据的位置(迭代器)
// 第一个参数为迭代器, 第二个位置为要插入的元素个数, 第三个位置为元素的值
v.insert(v.begin()+1, 3, 8); // 在第二个元素的位置插入 3 个 8, 无返回值
// 第一个参数为迭代器, 第二个位置为要插入的元素个数, 第三个位置为元素的值
v.insert(v.begin()+1, v_.begin(), v_.end()); // 在第二个元素的位置插入从begin到end的元素, 无返回值
删除元素
- 删除整个 vector 中的元素, 但是保留原有的容积
v.clear();
- 删掉单个元素
v.erase(v.begin()+1);
- 删除区间内的元素(左闭右开)
v.erase(v.begin(), v.begin()+3);