简单说来 set(集合)里的元素 不会有相同元素(也就是说 相同的值不存 )并且 存进去会自动排序 

类比sort默认排序从小到大 set排序也是

set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复(重复元素只操作一遍,其他的忽略处理),而后者允许。(因为插入的时候,它们分别调用的是insert和unique_insert)

同理,map和multimap也是这个意思。set、map它们的底层都是基于红黑树

set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。

平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque、和list的容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值从小到大的顺序排列。

set的各成员函数列表如下:

c++ stl容器set成员函数:begin()--返回指向第一个元素的迭代器

c++ stl容器set成员函数:clear()--清除所有元素

c++ stl容器set成员函数:count()--返回某个值元素的个数

c++ stl容器set成员函数:empty()--如果集合为空,返回true

c++ stl容器set成员函数:end()--返回指向最后一个元素的迭代器

c++ stl容器set成员函数:equal_range()--返回集合中与给定值相等的上下限的两个迭代器

c++ stl容器set成员函数:erase()--删除集合中的元素

c++ stl容器set成员函数:find()--返回一个指向被查找到元素的迭代器

c++ stl容器set成员函数:get_allocator()--返回集合的分配器

c++ stl容器set成员函数:insert()--在集合中插入元素

c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器

c++ stl容器set成员函数:key_comp()--返回一个用于元素间值比较的函数

c++ stl容器set成员函数:max_size()--返回集合能容纳的元素的最大限值

c++ stl容器set成员函数:rbegin()--返回指向集合中最后一个元素的反向迭代器

c++ stl容器set成员函数:rend()--返回指向集合中第一个元素的反向迭代器

c++ stl容器set成员函数:size()--集合中元素的数目

c++ stl容器set成员函数:swap()--交换两个集合变量

c++ stl容器set成员函数:upper_bound()--返回大于某个值元素的迭代器

c++ stl容器set成员函数:value_comp()--返回一个用于比较元素间的值的函数

set的常用操作:(在set中查找是使用二分查找

1、创建set集合对象

1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 set<int> s;
7 return 0;
8 }

2、元素的插入与中序遍历
  采用insert()方法把元素插入到集合中,插入规则在默认的比较规则下,是按元素值从小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。使用前向迭代器对集合中序遍历,结果正好是元素排序后的结果。

 1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 set<int> s;
7 s.insert(5); //第一次插入5,可以插入
8 s.insert(1);
9 s.insert(6);
10 s.insert(3);
11 s.insert(5); //第二次插入5,重复元素,不会插入
12 set<int>::iterator it; //定义前向迭代器
13 //中序遍历集合中的所有元素
14 for(it = s.begin(); it != s.end(); it++)
15 {
16 cout << *it << " ";
17 }
18 cout << endl;
19 return 0;
20 }
21 //运行结果:1 3 5 6

问题 存疑

3、元素的反向遍历
  使用反向迭代器reverse_iterator可以反向遍历集合,输出的结果正好是集合元素的反向排序结果。它需要用到rbegin()和rend()两个方法,它们分别给出了反向遍历的开始位置和结束位置。

 1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 set<int> s;
7 s.insert(5); //第一次插入5,可以插入
8 s.insert(1);
9 s.insert(6);
10 s.insert(3);
11 s.insert(5); //第二次插入5,重复元素,不会插入
12 set<int>::reverse_iterator rit; //定义反向迭代器
13 //反向遍历集合中的所有元素
14 for(rit = s.rbegin(); rit != s.rend(); rit++)
15 {
16 cout << *rit << " ";
17 }
18 cout << endl;
19 return 0;
20 }
21 //运行结果:6 5 3 1

4、元素的删除
  与插入元素的处理一样,集合具有高效的删除处理功能,并自动重新调整内部的红黑树的平衡。删除的对象可以是某个迭代器位置上的元素、等于某键值的元素、一个区间上的元素和清空集合。

 1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 set<int> s;
7 s.insert(5); //第一次插入5,可以插入
8 s.insert(1);
9 s.insert(6);
10 s.insert(3);
11 s.insert(5); //第二次插入5,重复元素,不会插入
12 s.erase(6); //删除键值为6的元素
13 set<int>::reverse_iterator rit; //定义反向迭代器
14 //反向遍历集合中的所有元素
15 for(rit = s.rbegin(); rit != s.rend(); rit++)
16 {
17 cout << *rit << " ";
18 }
19 cout << endl;
20 set<int>::iterator it;//定义正向迭代器
21
22 it = s.begin();
23 for(int i = 0; i < 2; i++)
24 it = s.erase(it); //删除正向前两个元素,只剩下最后元素5
25 for(it = s.begin(); it != s.end(); it++)
26 cout << *it << " ";
27 cout << endl;
28
29 s.clear();//清空set
30 cout << s.size() << endl;
31
32 return 0;
33 }
34 /*
35 运行结果:
36 5 3 1
37 5
38 0
39 */

5、元素的检索
  使用find()方法对集合进行检索,如果找到查找的的键值,则返回该键值的迭代器位置;否则,返回集合最后一个元素后面的一个位置,即end()。

 1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 set<int> s;
7 s.insert(5); //第一次插入5,可以插入
8 s.insert(1);
9 s.insert(6);
10 s.insert(3);
11 s.insert(5); //第二次插入5,重复元素,不会插入
12 set<int>::iterator it;
13 it = s.find(6); //查找键值为6的元素
14 if(it != s.end())
15 cout << *it << endl;//找到输出要找的元素的值
16 else
17 cout << "not find it" << endl;
18 it = s.find(20);
19 if(it != s.end())
20 cout << *it << endl;
21 else
22 cout << "not find it" << endl;
23 return 0;
24 }
25 /*
26 运行结果:
27 6
28 not find it
29 */

6、自定义比较函数

  使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数奖该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用默认的比较函数,即按键值从小到大的顺序插入元素。但在很多情况下,需要自己编写比较函数。

编写比较函数有两种方法。

(1)如果元素不是结构体,那么可以编写比较函数。下面的程序比较规则为按键值从大到小的顺序插入到集合中。

 1 #include<iostream>
2 #include<set>
3 using namespace std;
4 //自定义比较函数mycomp,重载操作符 ()
5 struct mycomp
6 {
7 bool operator() (const int &a, const int &b)
8 {
9 return a > b; //从大到小排序
10 //return a < b; //从小到大排序
11 }
12 };
13 int main()
14 {
15 set<int, mycomp> s; //采用比较函数mycomp
16 s.insert(5); //第一次插入5,可以插入
17 s.insert(1);
18 s.insert(6);
19 s.insert(3);
20 s.insert(5); //第二次插入5,重复元素,不会插入
21 set<int,mycomp>::iterator it;
22 for(it = s.begin(); it != s.end(); it++)
23 cout << *it << " ";
24 cout << endl;
25 return 0;
26 }
27 /*
28 运行结果:6 5 3 1
29 */

(2)如果元素是结构体,那么可以直接把比较函数写在结构体内。

 1 #include<iostream>
2 #include<set>
3 #include<string>
4 using namespace std;
5 struct Info
6 {
7 string name;
8 double score;
9 bool operator < (const Info &a) const // 重载“<”操作符,自定义排序规则
10 {
11 //按score由大到小排序。如果要由小到大排序,使用“>”即可。
12 return a.score < score;
13 }
14 };
15 int main()
16 {
17 set<Info> s;
18 Info info;
19
20 //插入三个元素
21 info.name = "Jack";
22 info.score = 80;
23 s.insert(info);
24 info.name = "Tom";
25 info.score = 99;
26 s.insert(info);
27 info.name = "Steaven";
28 info.score = 60;
29 s.insert(info);
30
31 set<Info>::iterator it;
32 for(it = s.begin(); it != s.end(); it++)
33 cout << (*it).name << " : " << (*it).score << endl;
34 return 0;
35 }
36 /*
37 运行结果:
38 Tom : 99
39 Jack : 80
40 Steaven : 60
41 */

7、equal_range() 的使用 ,返回一对定位器,分别表示第一个大于或等于给定关键值的元素和第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。

 1 #include <iostream>
2 #include <set>
3
4 using namespace std;
5
6 int main()
7 {
8 set<int> s;
9 set<int>::iterator iter;
10 for(int i = 1 ; i <= 5; ++i)
11 {
12 s.insert(i);
13 }
14 for(iter = s.begin() ; iter != s.end() ; ++iter)
15 {
16 cout<<*iter<<" ";
17 }
18 cout<<endl;
19 pair<set<int>::const_iterator,set<int>::const_iterator> pr;
20 pr = s.equal_range(3);
21 cout<<"第一个大于等于 3 的数是 :"<<*pr.first<<endl;
22 cout<<"第一个大于 3的数是 : "<<*pr.second<<endl;
23 return 0;
24 }

8、erase(iterator)  ,删除定位器iterator指向的值

   erase(first,second),删除定位器first和second之间的值

erase(key_value),删除键值key_value的值

 1 #include <iostream>
2 #include <set>
3
4 using namespace std;
5
6 int main()
7 {
8 set<int> s;
9 set<int>::const_iterator iter;
10 set<int>::iterator first;
11 set<int>::iterator second;
12 for(int i = 1 ; i <= 10 ; ++i)
13 {
14 s.insert(i);
15 }
16 //第一种删除
17 s.erase(s.begin());
18 //第二种删除
19 first = s.begin();
20 second = s.begin();
21 second++;
22 second++;
23 s.erase(first,second);
24 //第三种删除
25 s.erase(8);
26 cout<<"删除后 set 中元素是 :";
27 for(iter = s.begin() ; iter != s.end() ; ++iter)
28 {
29 cout<<*iter<<" ";
30 }
31 cout<<endl;
32 return 0;
33 }

set中的删除操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。

9、lower_bound(key_value)  ,返回第一个大于等于key_value的定位器

upper_bound(key_value), 返回最后一个大于等于key_value的定位器

 1 #include <iostream>
2 #include <set>
3
4 using namespace std;
5
6 int main()
7 {
8 set<int> s;
9 s.insert(1);
10 s.insert(3);
11 s.insert(4);
12 cout<<*s.lower_bound(2)<<endl;
13 cout<<*s.lower_bound(3)<<endl;
14 cout<<*s.upper_bound(3)<<endl;
15 return 0;
16 }

c++ stl库中的set的更多相关文章

  1. STL库中string类内存布局的探究

    在STL中有着一个类就是string类,他的内存布局和存储机制究竟是怎么样的呢? 这就是建立好的string 可以看出,图中用黄色框框标注的部分就是主要区域 我们用来给string对象进行初始化的字符 ...

  2. 关于STL库中的max min swap

    嗯...   不得不说c++中的STL库是一个神奇的东西   可以使你的代码显得更加简洁....   今天就只讲STL中的三个鬼畜:   max       min       swap   具体操作 ...

  3. STL库中的正态分布函数

    在设计抽奖一类程序中,有时会需要一种概率“有较大可能获得一个普通结果,有较小可能获得一个糟糕或极好的结果”,这就可以用正态分布函数来获得这样一个结果. STL中已经提供了一系列随机分布的函数,包括正态 ...

  4. C++STL 库中set容器应用

    #include<iostream> #include<cstdio> #include<set> using namespace std; set<int& ...

  5. C++STL库中vector容器常用应用

    #include<iostream> #include<vector> #include<algorithm> using namespace std; int m ...

  6. C++STL库中map容器常用应用

    #include<iostream> #include<cstdio> #include<map> //按键值大小构成二叉搜索树 using namespace s ...

  7. STL库中的equal_range()

    equal_range根据键值,返回一对迭代器的pair对象.如果该键值在容器中存在,则pair对象中的第一个迭代器指向该键关联的第一个实例,第二个迭代器指向该键关联的最后一个实例的下一位置.如果找不 ...

  8. STL库中神奇函数nth_element

    用法:nth_element(数组名,数组名+第k小元素,数组名+元素个数) 这个函数主要用来将数组元素中第k小的整数排出来并在数组中就位,随时调用. 例如: ]={,,,,},k ; cin> ...

  9. STL 库中的陷阱----一个难以察觉的 bug

    请找出下面程序的 bug? int maxProfit2(vector<int> &prices) { int local[3] = {0}; int global[3] = {0 ...

随机推荐

  1. Oracle学习(十七)数据库锁在分布式系统里的应用(老板,乐观锁了解一下?~)

    一.引言 随着业务量的增加,单机部署已经无法满足日常需求了,我们可能会把代码部署到多台服务器上去来进行服务的扩容,也就是负载均衡,那在这种场景下,怎么能实现锁的概念呢? 那么我们知道如果是一台主机部署 ...

  2. subDomainsBrute安装(windows系统)

    step1:  安装python2.7(省略) step2:  下载subDomainsBrute 地址: https://github.com/lijiejie/subDomainsBrute 下载 ...

  3. 手把手教你在 TKE 集群中实现简单的蓝绿发布和灰度发布

    概述 如何在腾讯云 Kubernetes 集群实现蓝绿发布和灰度发布?通常要向集群额外部署其它开源工具来实现,比如 Nginx Ingress,Traefik 等,或者让业务上 Service Mes ...

  4. iOS14剪切板探究,淘宝实现方法分析

    随着iOS 14的发布,剪切板的滥用也被大家所知晓.只要是APP读取剪切板内容,系统都会在顶部弹出提醒,而且这个提醒不能够关闭.这样,大家在使用APP的过程中就能够看到哪些APP使用了剪切板. 正好我 ...

  5. Java学习day05

    Java学习day05 [switch]属于选择结构,分支语句 语法结构: /* switch(int或string类型字面值或变量) { case int或string类型字面值或变量 : java ...

  6. 064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法

    064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法 本文知识点:无参带返回值方法 说明:因为时间紧张,本人写博客过程中只是对知识点的关键步骤进 ...

  7. 021 01 Android 零基础入门 01 Java基础语法 03 Java运算符 01 赋值运算符

    021 01 Android 零基础入门 01 Java基础语法 03 Java运算符 01 赋值运算符 本文知识点:Java中的赋值运算符 赋值运算符 赋值运算符从右往左运算 赋值运算符左边不能是常 ...

  8. Office远程代码执行漏洞(CVE-2017-11882)

    POC: https://github.com/Ridter/CVE-2017-11882/ 一.简单的生成弹计算器的doc文件. 网上看到的改进过的POC,我们直接拿来用,命令如下: #python ...

  9. Visual Studio中Debug与Release以及x86、x64、Any CPU的区别 &&&& VS中Debug与Release、_WIN32与_WIN64的区别

    本以为这些无关紧要的 Debug与Release以及x86.x64.Any CPU 差点搞死人了. 看了以下博文才后怕,难怪我切换了一下模式,程序就pass了.... 转载: 1.https://ww ...

  10. 【比赛记录】8.21 div2

    A 选择一个点\(B(x,0)\)使得\(|dis(A,B)-x|=k.\) 题目实际上就是找到一个最接近\(n\)的数,使得它可以分成两个数\(a,b,\)使\(a-b=k.\) 我们考虑先分成一个 ...