简单说来 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. Anaconda简介及特点

    摘要 Python是一种面向对象的解释型计算机程序设计语言,其使用,具有跨平台的特点,可以在Linux.macOS以及Windows系统中搭建环境并使用,其编写的代码在不同平台上运行时,几乎不需要做较 ...

  2. 12.扩展:向量空间模型算法(Vector Space Model)

  3. Boolean.valueOf(String)

    Boolean.valueOf(String) a. 当 String 的参数值在不区分大小写的时候等于 "true" ,则 Boolean.valueOf(String) 返回值 ...

  4. Oracle学习(十三)优化专题

    一.查询频繁,数据量大 索引 使用时机:表中经常查询的字段可以考虑添加索引. 联合索引:若能确认多个条件会同时使用时,可以将这几个条件作为联合索引. 单列索引:若条件查询时,这几个条件不是同时用到的话 ...

  5. xss利用——BeEF#stage3(绕过同源策略与浏览器代理)

    绕过同源策略 正式进入攻击阶段.因为SOP(同源策略)的存在,BeEF只能对被勾子钩住的页面所在域进行操作.如果有办法绕过SOP,那么无疑会使攻击面放大. 绕过SOP可从两方面入手.第一个是从浏览器本 ...

  6. 【Processing-日常4】等待动画2

    之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/79781034

  7. 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 02 封装的代码实现

    088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 02 封装的代码实现 本文知识点:Java封装的代码实现 说明:因为时间紧张,本人写博客过程中只 ...

  8. 《C++ primerplus》第13章练习题

    1.对CD类的派生练习.基类CD类存储作者和作品号等信息,派生类Classic额外增加一格"主要作品"的信息.主函数使用拷贝构造函数.按引用传递参数的函数和指针来测试基类和派生类的 ...

  9. 【题解】SP10570 【LONGCS - Longest Common Substring】

    \(\color{Red}{Link}\) \(\text{Solution:}\) 还是\(\text{Suffix Tree.}\) 根据\(\color{Blue}{Link}\)我们可以得到一 ...

  10. [POI2005]SAM-Toy Cars 贪心+堆

    [POI2005]SAM-Toy Cars 题目:Jasio 是一个三岁的小男孩,他最喜欢玩玩具了,他有n 个不同的玩具,它们都被放在了很高的架子上所以Jasio 拿不到它们:为了让他的房间有足够的空 ...