vector
# vector的定义
- vector是表示可变大小数组的序列容器。
- vector就像数组一样,也采用的连续空间来存储元素,这也意味着可以采用下标对vector的元素进行访问。
- vector与普通数组不同的是,vector的大小是可以动态改变的。
- 当vector需要重新分配大小时,其做法是,分配一个新的数组,然后将全部元素移到这个数组当中,并释放原来的数组空间。
- vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因此存储空间比实际需要的存储空间一般更大。不同的库采用不同的策略权衡空间的使用和重新分配,以至于在末尾插入一个元素的时候是在常数的时间复杂度完成的。
- 由于vector采用连续的空间来存储元素,与其他动态序列容器相比,vector在访问元素的时候更加高效,在其末尾添加和删除元素相对高效,而对于不在其末尾进行的删除和插入操作效率则相对较低。
# vector的构造函数
vector<int> v1; //构造int类型的空容器
vector<int> v2(10, 2); //构造含有10个2的int类型容器
vector<int> v3(v2); //拷贝构造int类型的v2容器的复制品
vector<int> v4(v2.begin(), v2.end()); //使用迭代器拷贝构造v2容器的某一段内容
1
2
3
4
2
3
4
第四种方式,还可以以下操作:
string s("hello world");
vector<char> v5(s.begin(), s.end()); //拷贝构造string对象的某一段内容
1
2
2
# vector的大小和容量
# size和capacity
通过size函数获取当前容器中的有效元素个数,通过capacity函数获取当前容器的最大容量。
# reserve和resize
通过reserse函数改变容器的最大容量,resize函数改变容器中的有效元素个数。
reserve规则: 1、当所给值大于容器当前的capacity时,将capacity扩大到该值。 2、当所给值小于容器当前的capacity时,什么也不做。
resize规则: 1、当所给值大于容器当前的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则默认为0。 2、当所给值小于容器当前的size时,将size缩小到该值。
# 迭代器的使用
同string
类似,vector的迭代器也分为正向和反向迭代器,以及是否用const
修饰
vector<int>::iterator it = v.begin();
while (it != v.end()) {
cout << *it << " ";
it++;
}
vector<int>::reverse_iterator rit = v.rbegin();
while (rit != v.rend()) {
cout << *rit << " ";
rit++;
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 迭代器失效问题
迭代器的主要作用就是让我们在使用各个容器时不用关心其底层的数据结构,而vector的迭代器在底层实际上就是一个指针。迭代器失效就是指迭代器底层对应指针所指向的空间被销毁了,而指向的是一块已经被释放的空间,如果继续使用已经失效的迭代器,程序可能会崩溃。
# 示例
示例1:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
//v: 1 2 3 4 5
vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器
v.insert(pos, 10); //在值为2的元素的位置插入10
//v: 1 10 2 3 4 5
v.erase(pos); //删除元素2 ???error(迭代器失效)
//v: 1 2 3 4 5
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
示例2:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (size_t i = 1; i <= 6; i++) {
v.push_back(i);
}
vector<int>::iterator it = v.begin();
while (it != v.end()) {
if (*it % 2 == 0) { //删除容器当中的全部偶数
v.erase(it);
}
it++;
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 解决方案
笔记
使用迭代器时,永远记住一句话:每次使用前,对迭代器进行重新赋值。
示例1的解决:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
//v: 1 2 3 4 5
vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器
v.insert(pos, 10); //在值为2的元素的位置插入10
//v: 1 10 2 3 4 5
pos = find(v.begin(), v.end(), 2); //重新获取值为2的元素的迭代器
v.erase(pos); //删除元素2
//v: 1 10 3 4 5
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
示例2的解决:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
for (size_t i = 1; i <= 6; i++) {
v.push_back(i);
}
vector<int>::iterator it = v.begin();
while (it != v.end()) {
if (*it % 2 == 0) {//删除容器当中的全部偶数
it = v.erase(it); //删除后获取下一个元素的迭代器
}
else {
it++; //是奇数则it++
}
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# vector的增删
# push_back和puah_pop
vector<int> v;
v.push_back(1); //尾插元素1
v.push_back(2); //尾插元素2
v.push_back(3); //尾插元素3
v.push_back(4); //尾插元素4
v.pop_back(); //尾删元素
v.pop_back(); //尾删元素
v.pop_back(); //尾删元素
v.pop_back(); //尾删元素
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# insert和erase
iterator insert (iterator position, const value_type& val);
void insert (iterator position, size_type n, const value_type& val); //插入n个val再position
iterator erase (iterator position);
iterator erase (iterator first, iterator last); //删除 [first,last) 的元素
1
2
3
4
5
2
3
4
5
感谢阅读!
# from cen
上次更新: 2025/01/13, 20:12:11