vector ,注意模版
api
构造
推荐设置初始容量减少扩容次数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> v; vector<int> v2(10); vector<int> v3(10, 1); vector<int> v4{1, 2, 3, 4, 5}; vector<int> v5(v4); int a[] = {1, 2, 3, 4, 5}; vector<int> v6(a, a + 5); return 0; }
|
其他
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> v(10); cout << v.size() << endl;
cout << v.capacity() << endl;
cout << v.empty() << endl;
v.resize(5); cout << v.size() << endl;
v.push_back(1);
v.emplace_back(2);
v.insert(v.begin(), 2, 3);
v.insert(v.begin() + 1, 4);
v.insert(v.end(), 5, 6);
cout << v[0] << endl; cout << v.at(0) << endl;
v.pop_back();
v.erase(v.begin() + 1);
v.erase(v.begin() + 1, v.end() - 1);
cout << v.front() << endl;
cout << v.back() << endl;
v.clear(); cout << v.size() << endl; cout << v.empty() << endl; cout << v.capacity() << endl; return 0; }
|
遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> vec = {1, 2, 3, 4, 5};
for (int i = 0; i < vec.size(); i++) { cout << vec.at(i) << " "; } cout << endl;
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) { cout << *it << " "; } cout << endl;
for (auto it = vec.begin(); it != vec.end(); it++) { cout << *it << " "; } cout << endl;
for (const auto &item : vec) { cout << item << " "; } return 0; }
|
并发修改异常
描述
下方容器元素使用相同的做测试(使用不同元素,可能结果正确,但是实际类似数组越界【可能不报错,未定义行为】)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> vec = {3, 3, 3, 3}; for (auto it = vec.begin(); it != vec.end(); it++) { if (*it == 3) { vec.erase(it); } } return 0; }
|
调试查看容器是[3,3],为什么没有全部删除,为什么是3,3?
- 开始it=0,删除第一个3,容器元素前移为[3,3,3]
- it=1,删除此时的第二个元素,容器变为[3,3]
- it=2,删除此时的第三个元素,显然未定义
也可能系统崩溃,总之未定义行为
解决
原因,容器元素前移导致迭代器指向问题
- 方式1:从后遍历删除,容器不前移即可
- 方式2:更新迭代器指向,使用
vec.erase(it)的返回值
- 方式3:标记删除,把不删除的元素放到新容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> vec = {3, 3, 3, 3};
for (int i = vec.size() - 1; i >= 0; i--) { if (vec.at(i) == 3) { vec.erase(vec.begin() + i); } }
vector<int> vec1 = {3, 3, 3, 3};
for (auto it = vec1.end() - 1; it >= vec1.begin(); it--) { if (*it == 3) { vec1.erase(it); } }
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> vec = {3, 3, 3, 3};
for (auto it = vec.begin(); it != vec.end();) { if (*it == 3) { it = vec.erase(it); } else { ++it; } } return 0; }
|
- 第一次,it=0,删除第一个=3,容器前移[3,3,3]
- 第一次后,此时的it指向的是原来的第二个元素(之前的元素的后一个元素),该元素就是此时【3,3,3】的第一个3,第二次满足条件删除第一个3,此时it指向第二个3,就是元素前移的第一个3
- …
- 即迭代器始终指向有效位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> vec = {3, 3, 3, 3, 4};
vector<int> vec2; for (auto it = vec.begin(); it != vec.end(); ++it) { if (*it != 3) { vec2.push_back(*it); } } vec = vec2; return 0; }
|
扩容机制
- 底层动态数组(堆存储,连续存储,随机访问【下标】),容量不足自动扩容
- 扩容原理:在内存中动态创建更大的新数组,将原数组数据复制到新数组,指针指向新数组,然后释放旧数组的内存空间
- 扩容大小:添加元素时自动检查是否需要扩容,扩容公式(n是本次要插入的元素个数)
$$
newSize=currentSize+max(currentSize,n)
$$
- 如果从0开始,每次插入一个元素,则扩容规律为$currentSize=2^{n-1}$,n代表扩容次数。如100需要要扩容8次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <vector>
using namespace std;
int main() { vector<int> v; v.push_back(1); cout << v.capacity() << endl; v.push_back(2); cout << v.capacity() << endl; v.push_back(3); cout << v.capacity() << endl;
v.push_back(4); cout << v.capacity() << endl;
v.clear(); cout << v.size() << endl; cout << v.capacity() << endl; return 0; }
|