关于set

set是以特定的顺序存储相异元素的容器。

set是关联式容器,C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。

查找、插入、删除的时间复杂度都是O(logn)

一些特点:

1、在插入或赋初值时会自动排序(除非是unordered_set)

2、不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素

3、不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数

4、每次insert或者erase之后,以前保存的iterator不会失效(关联式容器,只改变了一些指针的指向,原指针指向的内存没变)(当然,直接erase保存的指针肯定改变了)

set中的模板函数

begin()    返回指向第一个元素的迭代器

end()       返回指向最后一个元素的后一个位置的迭代器

clear()    清空内容

size()     返回当前元素个数

 

count(key_value)  用来查找set中某个键值出现的次数,在set只可能为0或1

erase(key_value)       删除键值为key_value的元素

erase(iterator)            删除迭代器iterator指向的元素

erase(first,second)    删除迭代器first和second之间的元素,[first,second)

find(key_value)          返回指向key_value的迭代器,如果没有找到返回end()

insert(key_value)      将key_value插入到set中

 

lower_bound(key_value)    返回第一个大于等于key_value的迭代器

upper_bound(key_value)   返回第一个大于key_value的迭代器

equal_range(key_value)     返回一对迭代器,first等同于lower_bound,second_bound等同于upper_bound,即 [lower_bound,upper_bound)

 

//若set<int>a,b; vector<int>c

set_union(a.begin(),a.end(),b.begin(),b.end(),back_insert(c))                        并集

set_intersection(a.begin(),a.end(),b.begin(),b.end(),back_insert(c))        交集

set_difference(a.begin(),a.end(),b.begin(),b.end(),back_insert(c))          差集

set_symmetric_difference(a.begin(),a.end(),b.begin(),b.end(),back_insert(c)) 对称差

 

//使用实例

//初始化set

//这个参考资料好少啊,自己尝试了这几种



1 #include<cstdio>
2 #include<set>
3 using namespace std;
4
5 int main()
6 {
7 int arr[] = { 3,2,1,4,5 };
8
9 //定义时赋初值
10 set<int>st1{3,2,1,4,5};
11 set<int>st2 = { 3,2,1,4,5 };
12 set<int>st3(arr, arr + 5);
13
14 //先定义,后赋值
15 set<int>st4;
16 st4 = { 3,2,1,4,5 };
17 set<int>st5;
18 st5.insert(arr, arr + 5);
19
20 return 0;
21 }


 

 

//基本操作



1 #include<cstdio>
2 #include<set>
3 using namespace std;
4
5 int main()
6 {
7 int arr[] = { 8, 10, 3, 3, 4, 3, 2, 1 };
8 set<int>st(arr,arr + 8);
9
10 //遍历
11 //不像vector,只能通过迭代器进行间接存取
12 for (set<int>::iterator it = st.begin(); it != st.end(); it++)
13 printf("%d ", *it);
14 printf("\n");
15
16 //查找
17 //未找到返回end()
18 set<int>::iterator it = st.find(4);
19 if(it != st.end()) printf("%d\n", *it);
20
21 //插入
22 //返回值为pair<set<int>::iterator,bool>
23 st.insert(0); st.insert(5);
24
25 //删除
26 //不要去删除不存在的元素
27 st.erase(3); st.erase(11);
28
29 //计数,是否在集合中
30 if (st.count(3)) printf("In\n");
31 else printf("Out\n");
32
33 //上下界函数
34 set<int>::iterator it1 = st.lower_bound(10);
35 set<int>::iterator it2 = st.upper_bound(10);
36
37 //区间定位
38 pair<set<int>::const_iterator, set<int>::const_iterator>pr;
39 pr = st.equal_range(8);
40 if(pr.second != st.end()) printf("%d %d\n", *pr.first, *pr.second);
41
42 for (set<int>::iterator it = st.begin(); it != st.end(); it++)
43 printf("%d ", *it);
44 return 0;
45 }


 

 

//集合操作



1 #include<cstdio>
2 #include<set>
3 #include<vector>
4 #include<iterator> //inserter函数定义在里面
5 #include<algorithm> //set_union,set_intersection等定义在里面
6 using namespace std;
7
8
9 int main()
10 {
11 //若待处理的集合用vecter保存,必须确保无重复且有序
12 //若用vector保存结果,使用函数back_inserter(dest)
13 vector<int>v1 = { 1,3,4,5,7,10 };
14 vector<int>v2 = { 1,5,6,7,8,10,15 };
15 vector<int>dest1;
16 set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(dest1));
17 //set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(dest));
18 //set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(dest));
19 //set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(dest));
20
21 //若用set保存结果,使用函数inserter(dest,dest.begin())
22 set<int>dest2;
23 set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), inserter(dest2, dest2.begin()));
24
25 //若待处理的集合用set保存,可以无序重复(会自动去重、排序)
26 set<int>s1 = { 10,3,3,3,4,4,5,7,1 };
27 set<int>s2 = { 1,5,6,7,8,10,15 };
28 set<int>dest3;
29 set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), inserter(dest3, dest3.begin()));
30
31 return 0;
32 }


 

参考资料:

1、​http://www.cplusplus.com/reference/set/set/?kw=set

 


个性签名:时间会解决一切