STL -set

转载自:http://blog.csdn.net/LYHVOYAGE/article/details/22989659

set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的的数据结构, 在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值; 另外,还得确保根节点的左子树的高度与有字数的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意的是,它不会重复插入相同键值的元素,而采取 忽略处理。

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

        构造set集合的主要目的是为了快速检索,使用set前,需要在程序头文件中包含声明“#include<set>”。

1.创建set集合对象

           创建set对象时,需要指定元素的类型,这一点和其他容器一样。

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<set>  
  3. using namespace std;  
  4. int main()  
  5. {  
  6.     set<int> s;  
  7.     return 0;  
  8. }  

2.元素的插入与中序遍历

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

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  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()两个方法,它们分别给出了反向遍历的开始位置和结束位置。

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  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.元素的删除

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

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  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);   
  25.     for(it = s.begin(); it != s.end(); it++)  
  26.         cout << *it << " ";  
  27.     cout << endl;  
  28.   
  29.     s.clear();  
  30.     cout << s.size() << endl;  
  31.   
  32.     return 0;  
  33. }  
  34. /* 
  35. 运行结果: 
  36. 5 3 1 
  37. 0     
  38. */  

5.元素的检索

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

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  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. not find it    
  28. */  

下面这种方法也能判断一个数是否在集合中:

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  1. #include <cstdio>  
  2. #include <set>  
  3. using namespace std;  
  4. int main() {  
  5.     set <int> s;  
  6.     int a;  
  7.     for(int i = 0; i < 10; i++)  
  8.         s.insert(i);  
  9.     for(int i = 0; i < 5; i++) {  
  10.         scanf("%d", &a);  
  11.         if(!s.count(a)) //不存在  
  12.             printf("does not exist\n");  
  13.         else  
  14.             printf("exist\n");  
  15.     }  
  16.     return 0;  
  17. }  


6.自定义比较函数

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

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

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

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<set>  
  3. using namespace std;  
  4. struct mycomp  
  5. //自定义比较函数,重载“()”操作符  
  6.     bool operator() (const int &a, const int &b)  
  7.     {  
  8.         if(a != b)  
  9.             return a > b;  
  10.         else  
  11.             return a > b;  
  12.     }  
  13. };  
  14. int main()  
  15. {  
  16.     set<int, mycomp> s; //采用比较函数mycomp  
  17.     s.insert(5); //第一次插入5,可以插入  
  18.     s.insert(1);  
  19.     s.insert(6);  
  20.     s.insert(3);  
  21.     s.insert(5); //第二次插入5,重复元素,不会插入  
  22.     set<int,mycomp>::iterator it;  
  23.     for(it = s.begin(); it != s.end(); it++)  
  24.         cout << *it << " ";  
  25.     cout << endl;  
  26.     return 0;  
  27. }  
  28. /* 
  29. 运行结果:6 5 3 1   
  30. */  

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

[cpp] view plaincopy 在CODE上查看代码片派生到我的代码片
    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. */ 

转载于:https://www.cnblogs.com/PrayG/p/5719600.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习实战之一】:C++实现K-近邻算法KNN

本文不对KNN算法做过多的理论上的解释&#xff0c;主要是针对问题&#xff0c;进行算法的设计和代码的注解。 KNN算法&#xff1a; 优点&#xff1a;精度高、对异常值不敏感、无数据输入假定。 缺点&#xff1a;计算复杂度高、空间复杂度高。 适用数据范围&#xff1a;数值…

javascript设计模式-继承

javascript继承分为两种&#xff1a;类式继承&#xff08;原型链、extend函数&#xff09;、原型式继承&#xff08;对继承而来的成员的读和写的不对等性、clone函数&#xff09;。 类式继承-->prototype继承&#xff1a; 1 function Person(name){2 this.name …

GIS基础软件及操作(二)

原文 GIS基础软件及操作(二) 练习二、管理地理空间数据库 1.利用ArcCatalog 管理地理空间数据库 2.在ArcMap中编辑属性数据 第1步 启动 ArcCatalog 打开一个地理数据库 当 ArcCatalog打开后&#xff0c;点击, 按钮&#xff08;连接到文件夹&#xff09;. 建立到包含练习数据的…

libSVM分类小例C++

from&#xff1a;http://www.doczj.com/list_31/ 使用libSVM求解分类问题的C小例 1.libSVM简介 训练模型的结构体 struct svm_problem//储存参加计算的所有样本 { int l; //记录样本总数 double *y; //指向样本类别的组数 //prob.y new double[prob.l]; struct svm_node …

qunit 前端脚本测试用例

首先引用qunit 测试框架文件 <link rel"stylesheet" href"qunit-1.22.0.css"> <script src"qunit-1.22.0.js"></script> <div id"qunit"></div> <div id"qunit-fixture"></div>…

非常规文件名删除

生活中我们偶尔会遇到这样一件事&#xff1a;走在路上&#xff0c;突然感觉鞋底有东西&#xff0c;抬脚一看&#xff0c;是个泡泡糖。拿不掉&#xff0c;走路还一粘一粘的。要多难受有多难受&#xff01;同样在linux中也有这么一种文件名。看着不舒服&#xff0c;却删不掉。今天…

Machine Learning(Stanford)| 斯坦福大学机(吴恩达)器学习笔记【汇总】

from&#xff1a;https://blog.csdn.net/m399498400/article/details/52556168 定义本课程常用符号 训练数据&#xff1a;机器用来学习的数据 测试数据&#xff1a;用来考察机器学习效果的数据&#xff0c;相当于考试。 m 训练样本的数量&#xff08;训练集的个数) x 输入的…

模板匹配算法

from&#xff1a;https://blog.csdn.net/zhi_neng_zhi_fu/article/details/51029864 模板匹配(Template Matching)算法 模板匹配&#xff08;Template Matching&#xff09;是图像识别中最具代表性的方法之一。它从待识别图像中提取若干特征向量与模板对应的特征向量进行比较…

立体匹配十大概念综述---立体匹配算法介绍

from&#xff1a;https://blog.csdn.net/wintergeng/article/details/51049596 一、概念 立体匹配算法主要是通过建立一个能量代价函数&#xff0c;通过此能量代价函数最小化来估计像素点视差值。立体匹配算法的实质就是一个最优化求解问题&#xff0c;通过建立合理的能量函数…

zjnu1730 PIRAMIDA(字符串,模拟)

Description Sample Input 6 JANJETINA 5 1 J 1 A 6 N 6 I 5 E Sample Output 1 0 2 1 1题意&#xff1a;给你一个长度小于等于10^6的字符串&#xff0c;然后每次让它循环铺盖&#xff0c;构成层数为n的塔&#xff0c;让你求得第i层塔中某个字符的个数。 思路&#xff1a;首先要…

ICP算法理解

from&#xff1a;https://blog.csdn.net/linear_luo/article/details/52576082 1 经典ICP ICP的目的很简单&#xff0c;就是求解两堆点云之间的变换关系。怎么做呢&#xff1f;思路很自然&#xff0c;既然不知道R和t(针对刚体运动)&#xff0c;那我们就假设为未知量呗&#xf…

图像处理的灰度化和二值化

from&#xff1a;http://blog.sina.com.cn/s/blog_13c6397540102wqtt.html 在图像处理中&#xff0c;用RGB三个分量&#xff08;R&#xff1a;Red&#xff0c;G&#xff1a;Green&#xff0c;B&#xff1a;Blue&#xff09;&#xff0c;即红、绿、蓝三原色来表示真彩色&#x…

获取子元素

1、纯css 获取子元素 #test1>div {background-color:red;}#test1 div {font-size:14px;}#test1>div:first-child {color:#ccc;} <div id"test1"><div>性别</div><div>男</div></div> 因1示例中为#test1下的子元素 #test1…

44.Android之Shape设置虚线、圆角和渐变学习

Shape在Android中设定各种形状&#xff0c;今天记录下&#xff0c;由于比较简单直接贴代码。 Shape子属性简单说明一下:   gradient -- 对应颜色渐变。 startcolor、endcolor就不多说了。 android:angle是指从哪个角度开始变.solid -- 填充。stroke -- 描边。corners -- 圆角…

几种边缘检测算子的比较Roberts,Sobel,Prewitt,LOG,Canny

from&#xff1a;https://blog.csdn.net/gdut2015go/article/details/46779251 边缘检测是图像处理和计算机视觉中的基本问题&#xff0c;边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。这些包括&#xff1a;深度上的…

django 初试

/*************************************************************************************** django 初试* 说明&#xff1a;* 昨天打搭了dgango的服务器&#xff0c;今天学一下怎么来输出一个hello world出来。* * …

浅析“高斯白噪声”,“泊松噪声”,“椒盐噪声”的区别

from&#xff1a;https://www.jianshu.com/p/67f909f3d0ce 在图像处理的过程中&#xff0c;一般情况下都进行图像增强&#xff0c;图像增强主要包括“空域增强”和“频域增强”&#xff0c; 空域增强包括平滑滤波和锐化滤波。 平滑滤波&#xff0c;就是将图像模糊处理&#x…

Java 开发环境部署

1.下载Java开发环境工具包JDK&#xff0c;下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载后&#xff0c;双击jdk应用程序&#xff0c;根据提示完成安装&#xff0c;安装过程中可以自定义安装目录等信息&#xff0c;这里我选择…

枚举enum、NS_ENUM 、NS_OPTIONS

2019独角兽企业重金招聘Python工程师标准>>> enum 了解位移枚举之前&#xff0c;我们先回顾一下C语言位运算符。 1 << : 左移,比如1<<n,表示1往左移n位&#xff0c;即数值大小2的n次方; 例如 : 0b0001 << 1 变为了 0b0010 2 >> : 右…

数字图像处理-频率域滤波原理

from&#xff1a;https://blog.csdn.net/forrest02/article/details/55510711?locationNum15&fps1 写在前面的话 作者是一名在读的硕士研究僧&#xff0c;方向是图像处理。由于图像处理是一门相对复杂的学科&#xff0c;作者在课堂上学到的东西只是非常浅显的内容&#…