没有输出的输入是不完整的

0%

set的简单用法

本文为c++容器系列第六篇.
主要测试了set相关的方法,主要作为代码备份方便之后遗忘时查询。
set,multiset,unordered_set,unordered_multiset仅仅有稍许差别,方法和set基本类似,所以不再另行写文章啦。

写在最前面

  1. 由于set和unordered_set的功能几乎完全一致,用的时候记得引入unordered_set的头文件,然后声明对象的时候将set换成unordered_set就可以啦。就像是下面这样
1
2
3
4
// 引入头文件
#include <unordered_set>
// 声明对象
unordered_set<int> a = {1,2,3};

还需要注意的一点就是unordered_set是没有upper_bound和lower_bound方法的。
2. set和multiset都是通过set头文件导入的,multiset相比于set的不同点就在于可以插入相同的元素,用的时候记住就可以啦,所以也不再另行写文章,所有操作参考本文章就行。

set测试代码

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

#include <stdio.h>
#include <set>
#include <unordered_set>
#include <iostream>
using namespace std;

template<class T>
void printSet(const string s,const T& mset){
cout<<s<<'\t';
for(auto a:mset){
cout<<a<<'\t';
}
cout<<endl;
}

int main(){
// 声明
set<int> a;
set<int> a1 = {1,2,3};
set<int> a2(a1);
set<int> a3(a1.begin(),a1.begin());

printSet("a:", a);
printSet("a1:",a1 );
printSet("a2:", a2);
printSet("a3:", a3);

//capacity相关
cout<<"a.size(): "<<a.size()<<endl;
a.insert(1);
cout<<"after insert 1, a.size()"<<a.size()<<endl;
//set的特性就是不能插入重复元素,如果插入那么就会报错。
// a.insert(1);
//cout<<"a.size()"<<a.size()<<endl;
//printSet("after 2 time insert 1: ", a);

cout<<"a.empty(): "<<a.empty()<<endl;
cout<<"a.max_size(): "<<a.max_size()<<endl;

//modifiers
a.insert(3);
printSet("after insert 3: ", a);

auto find3 = a.find(3);
a.erase(find3);
printSet("after erase3: ", a);

a.clear();
printSet("after clear:", a);

a = {1,2,3,4,5};
// Look up相关
//find 会返回一个itertor
auto f = a.find(2);
if(f!=a.end()){
cout<<"find \t"<<*f<<endl;
}else{
cout<<"not found 2"<<endl;
}
cout<<"a.find(2)\t"<<*a.find(2)<<endl;
// count
cout<<"a.count(3): "<<a.count(3)<<endl;

// equal_range
auto equal2 = a.equal_range(2);
for(auto i = equal2.first; i != equal2.second; i++){
cout<<"equal2: "<<*i<<endl;
}

/*
如果我的equal_range判断的值在原来的set中没有会怎么样呢?会等价于a.end()
所以这里其实是告诉我们,在使用equal_range方法的时候,
要记得先判断一下返回的pair的第一个iterator指向的是否是end()。
或者在使用equal_range之前可以先通过find或者count先判断一下要找的key是存在的。
*/

auto equal6 = a.equal_range(6);
cout<<"equal6: "<<*equal6.first<<" "<<*equal6.second<<endl;
cout<<"equal6.first == a.end(): "<<(equal6.first == a.end())<<endl;
cout<<"equal6.second == a.end(): "<<(equal6.second == a.end())<<endl;

// 确认set中不会有重复元素,那么如果找到,则两个iterator之差肯定为1,
// 如果找不到,那么差为0,后来发现set的iterator也不可做差运算,此处存疑。


// upper_bound 和 lower_bound
auto ub = a.upper_bound(4);
auto lb = a.lower_bound(2);
cout<<"lower_bound(2): "<<*lb<<endl;
cout<<"upper_bound(4): "<<*ub<<endl;

// 遍历操作
set<int>::iterator iter = a.begin(); // 等价于auto iter = a.begin();
for(;iter!=a.end();iter++){
cout<<*iter<<'\t';
}


return 0;
}

/* 运行结果
a:
a1: 1 2 3
a2: 1 2 3
a3:
a.size(): 0
after insert 1, a.size()1
a.empty(): 0
a.max_size(): 576460752303423487
after insert 3: 1 3
after erase3: 1
after clear:
find 2
a.find(2) 2
a.count(3): 1
equal2: 2
equal6: 32766 32766
equal6.first == a.end(): 1
equal6.second == a.end(): 1
lower_bound(2): 2
upper_bound(4): 5
1 2 3 4 5 Program ended with exit code: 0
*/