set是STL中一种标准关联容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。set,顾名思义是“集合”的意思,在set中元素都是唯一的,而且默认情况下会对元素自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允许重复那么可以使用multiset
#include<set>
#include<iterator>
#include<iostream>
using namespace std;
int main()
{
set<int>eg1;
//插入
eg1.insert(1);
eg1.insert(100);
eg1.insert(5);
eg1.insert(1);//元素1因为已经存在所以set中不会再次插入1
eg1.insert(10);
eg1.insert(9);
//遍历set,可以发现元素是有序的
set<int>::iterator set_iter=eg1.begin();
cout<<"Set named eg1:"<<endl;
for(;set_iter!=eg1.end();set_iter++) cout<<*set_iter<<" ";
cout<<endl;
//使用size()函数可以获得当前元素个数
cout<<"Now there are "<<eg1.size()<<" elements in the set eg1"<<endl;
if(eg1.find(200)==eg1.end())//find()函数可以查找元素是否存在
   cout<<"200 isn't in the set eg1"<<endl;

set<int>eg2;
for(int i=6;i<15;i++)
eg2.insert(i);
cout<<"Set named eg2:"<<endl;
for(set_iter=eg2.begin();set_iter!=eg2.end();set_iter++)
   cout<<*set_iter<<" ";
cout<<endl;
//获得两个set的并
set<int>eg3;
cout<<"Union:";
set_union(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));//注意第五个参数的形式
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的交,注意进行集合操作之前接收结果的set要调用clear()函数清空一下
eg3.clear();
set_intersection(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
cout<<"Intersection:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的差
eg3.clear();
set_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
cout<<"Difference:";
copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
cout<<endl;
//获得两个set的对称差,也就是假设两个集合分别为A和B那么对称差为AUB-A∩B
   eg3.clear();
   set_symmetric_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));
   copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));
   cout<<endl;

return 0;
}

set会对元素进行排序,那么问题也就出现了排序的规则是怎样的呢?上面的示例代码我们发现对int型的元素可以自动判断大小顺序,但是对char*就不会自动用strcmp进行判断了,更别说是用户自定义的类型了,事实上set的标准形式是set<Key, Compare, Alloc>,

参数 描述 默认值
Key 集合的关键字和值的类型  
Compare 关键字比较函数,它的参数类型key参数指定的类型,如果第一个参数小于第二个参数则返回true,否则返回false less<Key>
Alloc set的分配器,用于内部内存管理 alloc

下面给出一个关键字类型为char*的示例代码

#include<iostream>
#include<iterator>
#include<set>
using namespace std;
struct ltstr
{
bool operator() (const char* s1, const char* s2) const
{
   return strcmp(s1, s2) < 0;
}
};

int main()
{
const int N = 6;
const char* a[N] = {"isomer", "ephemeral", "prosaic", 
   "nugatory", "artichoke", "serif"};
const char* b[N] = {"flat", "this", "artichoke",
   "frigate", "prosaic", "isomer"};

set<const char*,ltstr> A(a, a + N);
set<const char*,ltstr> B(b, b + N);
set<const char*,ltstr> C;

cout << "Set A: ";
//copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));
set<const char*,ltstr>::iterator itr;
for(itr=A.begin();itr!=A.end();itr++) cout<<*itr<<" ";
cout << endl;
cout << "Set B: ";
copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " "));   
cout << endl;

cout << "Union: ";
set_union(A.begin(), A.end(), B.begin(), B.end(),
    ostream_iterator<const char*>(cout, " "),
    ltstr());   
cout << endl;

cout << "Intersection: ";
set_intersection(A.begin(), A.end(), B.begin(),B.end(),ostream_iterator<const char*>(cout," "),ltstr());
cout<<endl;
set_difference(A.begin(), A.end(), B.begin(), B.end(),inserter(C, C.begin()),ltstr());
cout << "Set C (difference of A and B): ";
copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " "));
cout <<endl;
return 0;
}

其中的ltstr也可以这样定义
class ltstr
{
        public:
        bool operator() (const char* s1,const char*s2)const
        {
                return strcmp(s1,s2)<0;
        }
};

更加通用的应用方式那就是数据类型也是由用户自定义的类来替代,比较的函数自定义,甚至可以加上二级比较,比如首先按照总分数排序,对于分数相同的按照id排序,下面是示例代码

#include<set>
#include<iostream>
using namespace std;
struct
{
                int id;
                int score;
                string name;
};
struct compare
{
        bool operator()(const Entity& e1,const Entity& e2)const   {
                if(e1.score<e2.score) return true;
                else
                        if(e1.score==e2.score)
                                if(e1.id<e2.id) return true;

return false;
        }
};

int main()
{
        set<Entity,compare>s_test;
        Entity a,b,c;
        a.id=123;a.score=90;a.name="bill";
        b.id=121;b.score=85;b.name="mary";
        c.id=130;c.score=85;c.name="jerry";
        s_test.insert(a);s_test.insert(b);s_test.insert(c);
        set<Entity,compare>::iterator itr;
        cout<<"Score List(ordered by score):\n";
        for(itr=s_test.begin();itr!=s_test.end();itr++)
                cout<<itr->id<<"---"<<itr->name<<"---"<<itr->score<<endl;
        return 0;
}

STL中的Set用法(详+转)的更多相关文章

  1. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  2. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  3. php中setcookie函数用法详解(转)

    php中setcookie函数用法详解:        php手册中对setcookie函数讲解的不是很清楚,下面是我做的一些整理,欢迎提出意见.        语法:        bool set ...

  4. JavaScript中return的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...

  5. Mysql中limit的用法详解

    Mysql中limit的用法详解 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,为我们提供了limit这样一个功能. SELECT * FROM table LIMIT [offset ...

  6. STL中mem_fun, mem_fun_ref用法

    1.引言 先看一个STL中for_each的用法: #include <iostream> #include <vector> #include <algorithm&g ...

  7. JavaScript中this的用法详解

    JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...

  8. (转)Shell中read的用法详解

    Shell中read的用法详解 原文:http://blog.csdn.net/jerry_1126/article/details/77406500 read的常用用法如下: read -[pstn ...

  9. (转)linux 中特殊符号用法详解

    linux 中特殊符号用法详解 原文:https://www.cnblogs.com/lidabo/p/4323979.html # 井号 (comments)#管理员  $普通用户 脚本中 #!/b ...

  10. CentOS 7.X 中systemctl命令用法详解

    systemctl是RHEL 7 的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体.可以使用它永久性或只在当前会话中启用/禁用服务,下面来看CentOS 7.X 中 ...

随机推荐

  1. CLion之C++框架篇-安装工具,基础框架的搭建(一)

      背景   日常学习C++,也就是看看书.在vim里写写代码.在日常项目开发中,也是边看书(一是系统性理解.二是找找有什么更好的代码编写方式)边写代码,会顺带看看别人的代码怎么写的?     日常学 ...

  2. Java实现链表的常见操作算法

    链表分为单链表,双向链表和循环链表,是一种链式存储结构,由一个个结点链式构成,结点包含数据域和指针域,其中单链表是只有一个指向后驱结点的指针,双向链表除头结点和尾结点外,每个结点都有一个前驱指针和一个 ...

  3. python面试中被问的最多的10道题

    1 性能: 解析下面代码慢在哪里def strtest1(num):str='first'for i in range(num):str+="X"return str解析:pyth ...

  4. python基础-字符串(6)

    一.引言 当打来浏览器登录某些网站的时候,需要输入密码,浏览器把密码传送到服务器后,服务器会对密码进行验证,其验证过程是把之前保存的密码与本次传递过去的密码进行对比,如果相等,那么就认为密码正确,否则 ...

  5. [django]date类型和datetime类型过滤

    搞清楚datetime.datetime和datetime.date模块 他们两个的格式区别 datetime模块 In [1]: from datetime import datetime In [ ...

  6. 异步请求中jetty处理ServletRequestListener的坑

    标题起得比较诡异,其实并不是坑,而是jetty似乎压根就没做对异步request的ServletRequestListener的特殊处理,如果文中有错误欢迎提出,可能自己有所疏漏了. 之前遇到了一个b ...

  7. 通过 Emoji 表情标识 Git 每次提交的信息

    在 Git 提交时我们可以通过附加 emoji 表情来着重提醒其他开发人员本次地更改重点,也就是说我们可通过不同的表情可以快速地知道这次提交具体做了哪方面地工作. 比如说本次提交我添加了一个新的单元测 ...

  8. XMPP大杂烩

    XMPP大杂烩 对XMPP的理解 XMPP是基于XML的即时通讯协议.对即时通讯场景进行了高度抽象,比如用订阅对方的上下线状态表示好友.提供了文本通讯.用户上下线通知.联系人管理.群组聊天等功能,还可 ...

  9. 剑指offer--2

    前言:继续笔记分享! 面试题6:暂无好的解决方法先搁浅一下 面试题7: #include<stdio.h> #include<stdlib.h> typedef struct ...

  10. 新生命团队netcore服务器免费开放计划

    为了便于大家学习测试netcore,我们计划提供1~3台公网Linux服务器(CentOS/Ubuntu),1vCPU+1G内存+100Mbps,为期1年,每周重置系统修改一次密码.对使用者要求如下: ...