STL:set的使用

关于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("
");
15 
16     //查找
17     //未找到返回end()
18     set<int>::iterator it = st.find(4);
19     if(it != st.end())  printf("%d
", *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
");
31      else  printf("Out
");
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
", *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

2、https://blog.csdn.net/changjiale110/article/details/79108447

3、https://blog.csdn.net/rocky_56X/article/details/81772646

4、https://blog.csdn.net/yang20141109/article/details/51782027

原文地址:https://www.cnblogs.com/lfri/p/9996368.html