余睿的博客

浮生若梦,别多会少,不如莫遇

0%

c++ vector容器的使用

构造函数

vector的构造函数有以下几种重载

  1. 默认无参构造函数
  2. 使用{}内的内容初始化
  3. 使用一个以及存在的容器初始化
  4. 初始化为指定个数指定的内容
  5. 用数组进行初始化

注:所有的初始化方法都可以指定分配器,如下代码所示:

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
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& v)
{
s.put('[');
char comma[3] = { '\0', ' ', '\0' };
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}

int main() {
/**************构造函数***************/
vector<int> a;//默认无参构造函数,不含任何元素
vector<int> b{ 1,2,3,4,5 };//使用1,2,3,4,5去初始化
vector<int> c(b);//使用 b 初始化c
vector<int> d(10, 1);//初始化10个1
int arr[5] = { 1,2,3,4,5 };
vector<int> e(arr,arr+3);//使用数组arr的前3个元素初始化
vector<int> f(allocator<int>);//指定分配器

cout << "a=" << a << '\n';
cout << "b=" << b << '\n';
cout << "c=" << c << '\n';
cout << "d=" << d << '\n';
cout << "e=" << e << '\n';
return 0;
}

输出:

1
2
3
4
5
a=[]
b=[1, 2, 3, 4, 5]
c=[1, 2, 3, 4, 5]
d=[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
e=[1, 2, 3]

元素访问

对于元素的访问,c++提供了以下几种方法:

  1. at:访问指定元素,同时进行越界检测
  2. operator[]:访问指定下标元素
  3. front:访问第一个元素
  4. back:访问最后一个元素
  5. data:返回指向内存中数组第一个元素指针

at

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
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& v)
{
s.put('[');
char comma[3] = { '\0', ' ', '\0' };
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}

int main() {
/**************元素访问***************/
vector<int> data{ 1,2,3,4,5,6,7 };
data.at(1) = 10;//改变下标为1的元素

//访问下标为1的元素
cout << "data[1]=" << data.at(1) << '\n';

//捕获异常
try{
cout << "data[9]=" << data.at(9) << '\n';
}
catch (const std::out_of_range const& exc){
cout << exc.what() << '\n';
}
cout << "data=" << data << '\n';
return 0;
}

输出:

1
2
3
data[1]=10
invalid vector subscript
data=[1, 10, 3, 4, 5, 6, 7]

operator[]frontbackdata

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;

template<typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& v)
{
s.put('[');
char comma[3] = { '\0', ' ', '\0' };
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}

int main() {
vector<int> numbers = { 1,2,3,4 };
//operator[]
cout << "second element:" << numbers[1] << '\n';
numbers[0] = 101;
cout << "numbers=" << numbers << '\n';

//front
if (!numbers.empty()) {
cout << "the first number:" << numbers.front() << '\n';
}

//back
if (!numbers.empty()) {
cout << "the last number:" << numbers.back() << '\n';
}

//data
//size()为0可能不反回空
cout << "data:" << numbers.data() << '\n';
return 0;
}

输出:

1
2
3
4
5
second element:2
numbers=[101, 2, 3, 4]
the first number:101
the last number:4
data:000001CBBB6F1B80

容量

对于容量的检查,c++提供以下几个接口:

  1. empty():检查容器是否为空,是返回1,否则返回0
  2. size():返回容纳的元素个数
  3. max_size()返回可容纳的最大元素个数
  4. reserve()预留存储空间
  5. capacity()返回当前容器能够容纳的元素个数
  6. shrink_to_fit()释放未使用的内存减少内存的使用
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
#include<iostream>
#include<vector>
using namespace std;

int main() {
/**************容量***************/
cout << "**************容量***************\n";
//empty()
vector<int> numbers;
cout << "Initially, numbers.empty(): " << numbers.empty() << '\n';
numbers.push_back(1);
cout << "Initially, numbers.empty(): " << numbers.empty() << '\n';

//size()
cout << "nums contains " << numbers.size() << " elements.\n";
//max_size()
cout << "Maximum size of a 'vector' is " << numbers.max_size() << "\n";

//capacity
vector<int> v1;
int cap = v1.capacity();
for (int i = 0; i < 200; ++i) {
v1.push_back(i);
if (cap != v1.capacity()) {
cap = v1.capacity();
cout << "new capacity=" << cap << '\n';
}
}
cout << "final size=" << v1.size() << '\n';
cout << "final capacity=" << v1.capacity() << '\n';

//shink_to_fit
v1.shrink_to_fit();
cout << "shrink_to_fit capacity=" << v1.capacity() << '\n';

return 0;
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**************容量***************
Initially, nums.empty(): 1
Initially, nums.empty(): 1
nums contains 0 elements.
Maximum size of a 'vector' is 4611686018427387903
new capacity=1
new capacity=2
new capacity=3
new capacity=4
new capacity=6
new capacity=9
new capacity=13
new capacity=19
new capacity=28
new capacity=42
new capacity=63
new capacity=94
new capacity=141
new capacity=211
final size=200
final capacity=211
shrink_to_fit capacity=200

修改器

c++提供的用于容器数据修改的API接口有以下几个:

  1. clear():清空容器内容
  2. insert():插入元素
  3. emplace():替换元素
  4. erase():擦除元素
  5. push_back():将元素添加到容器末尾
  6. emplace_back():在元素尾部构造元素
  7. pop_back():移除末尾元素
  8. resize():改变容器中可存储元素的个数
  9. swap()交换两个容器内容
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
66
67
68
69
70
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
std::ostream& operator<<(std::ostream& s, const std::vector<T>& v)
{
s.put('[');
char comma[3] = { '\0', ' ', '\0' };
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}

int main() {
/**************修改器***************/
cout << "**************修改器***************\n";
//clear
vector<int> container{ 1,2,3 };
cout << "before clear:" << container << '\n';
container.clear();//清除容器内元素
cout << "after clear:" << container << '\n';

//push_back
cout << "before push_back=" << container << '\n';
for (int i = 0; i < 10; ++i)
container.push_back(i);//容器尾部添加元素i
cout << "after push_back=" << container << '\n';

//insert
cout << "before insert:" << container << '\n';
container.insert(container.begin(), 9);//在容器首部插入9
cout << "insert(container.begin(), 9):" << container << '\n';
auto it = find(container.begin(), container.end(), 3);
container.insert(it, 3, 100);//在位置it插入3个100
cout << "insert(it, 3, 100):" << container << '\n';
vector<int> g{ 12,14,16,18 };
container.insert(container.end(), g.begin(), g.end());//在容器最后插入容器g的内容
cout << "insert(container.end(), g.begin(), g.end()):" << container << '\n';

//emplace
container.emplace(container.begin(), 99);//将首元素替换为99
cout << "emplace the first element to 99:" << container << '\n';

//erase
container.erase(container.begin());//擦除首个元素
cout << "erase the first element:" << container << '\n';
container.erase(container.begin(), container.begin() + 2);//擦除区间[container.begin(), container.begin() + 2)
cout << "erase section:" << container << '\n';

//pop_back
container.pop_back();//将组后一个元素删除
cout << "pop_back:" << container << '\n';

//resize
container.resize(3);//改变容器大小为3,超出部分丢弃
cout << "resize(3):" << container << '\n';
container.resize(6);//改变容器大小为6,不够填充时使用0填充
container.resize(9, 66);//不够填充时用66填充

//swap
vector<int> h;
cout << "before swap:container=" << container << "\tgh=" << h << '\n';
container.swap(h);//交换container h
cout << "after swap:container=" << container << "\tgh=" << h << '\n';

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
**************修改器***************
before clear:[1, 2, 3]
after clear:[]
before push_back=[]
after push_back=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
before insert:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
insert(container.begin(), 9):[9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
insert(it, 3, 100):[9, 0, 1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9]
insert(container.end(), g.begin(), g.end()):[9, 0, 1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16, 18]
emplace the first element to 99:[99, 9, 0, 1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16, 18]
erase the first element:[9, 0, 1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16, 18]
erase section:[1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16, 18]
pop_back:[1, 2, 100, 100, 100, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16]
resize(3):[1, 2, 100]
before swap:container=[1, 2, 100, 0, 0, 0, 66, 66, 66] h=[]
after swap:container=[] h=[1, 2, 100, 0, 0, 0, 66, 66, 66]

迭代器

c++提供以下几种迭代器供使用:

  1. begin:返回指向起始的迭代器
  2. end:返回指向末尾的迭代器
  3. rbegin:返回指向起始的逆向迭代器
  4. rend:返回指向末尾的逆向迭代器

begin以及end见上述示例,rbegin以及rend见下图示例:

range-rbegin-rend.svg

返回指向逆向 vector 首元素的逆向迭代器。它对应非逆向 vector 的末元素。若 vector 为空,则返回的迭代器等于rend()

欢迎关注我的其它发布渠道