简单说来 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. mxgraph浅入

    mxgraph浅入 参考文献:https://www.cnblogs.com/xuxg/articles/3246206.html 1.了解 (1)如何判断需要引入mxgraph产品:过程图.工作流和 ...

  2. php+html实现用户登录退出

    随着渗透学习,逐渐意识到了学会开发也是非常重要的,仅仅是看懂感觉还是差了一些,所以写一写php的开发,这套程序目前并未有较完整的功能,之后会不断进行完善 登录页面.html <!DOCTYPE ...

  3. xss的编码原理

    把以前的笔记翻出来整理一下 最前方 xss如何选用编码原理,为什么 找到的挺清楚的文章了:https://www.cnblogs.com/p0laris/p/11898322.html浏览器解析有两种 ...

  4. java中的几种基础排序

    import java.util.Random;import java.util.Arrays; public class Puppy {     public static void main(St ...

  5. 深入了解Redis(6)-持久化原理

    Redis是一个内存数据库,数据保存在内存中.但我们都知道存储在内存中的数据会因为外部因素而丢失,所以Redis会把数据持久化到磁盘中,至于是如何持久化呢? 一.RDB 1.手动触发 save:该命令 ...

  6. 020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结

    020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结 本文知识点:变量与常量 知识总结 Java中的标识符 Java中的关键字 目前常 ...

  7. ANNdotNET中的视觉神经网络设计器

    ANNdotNET简介 是一个在.net平台上进行深度学习的开源项目.NET Framework和.NET Core).该项目位于http://github.com/bhrnjica/anndotne ...

  8. BeetleX之webapi使用入门

    BeetleX是TCP通讯应用组件,在它之上可以扩展任何基于TCP的应用通讯功能.FastHttpApi是组件扩展的一个Http/Https/Websocket服务组件,它提供的功能丰富,包括功能有: ...

  9. 第一个月多测师讲解__项目讲解以及注意事项(肖sir)

    一.目的讲解流程:(讲述业务时长10-15分钟为宜)1.自我介绍礼貌用语,姓名,籍贯,学校,个人技能,经验,表现,兴趣爱好等 ,1分钟 ,谢谢2.介绍项目的名字 ,项目的背景,(涉及什么架构)3.对项 ...

  10. Python--网络爬虫模块requests模块之响应--response

    当requests发送请求成功后,requests就会得到返回值,如果服务器响应正常,就会接收到响应数据: Response响应中的属性和方法 常用属性: status_code: 数据类型:int ...