1. 程式人生 > >STL:set的使用

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("\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

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