一、set定义

c++官方对set的定义如下:

Set:Sets are containers that store unique elements following a specific order.
Set:set是一类用来存储满足一定排序的独一元素的容器。

类模板如下:

template < class T,                        // set::key_type/value_typeclass Compare = less<T>,        // set::key_compare/value_compareclass Alloc = allocator<T>      // set::allocator_type> class set;

可以看到set模板类有三个参数:

  1. T:set容器中的元素类型。
  2. Compare:比较类,定义容器中元素排序,缺省为less< T >。
  3. Alloc:内存分配器。一般使用缺省值。

二、set< int >实例

 set<int, less<int> > set_less;set<int, greater<int> > set_greater;for(int i=0; i<10; i++){set_less.insert(i%3);set_greater.insert(i%3);}// 遍历for(set<int, less<int> >::iterator iter=set_less.begin(); iter!=set_less.end(); iter++){cout<<*iter<<" ";}cout<<endl;for(set<int, greater<int> >::iterator iter=set_greater.begin(); iter!=set_greater.end(); iter++){cout<<*iter<<" ";}

输出为:

0 1 2
2 1 0

三、set< pair< int , int>>实例

1.默认pair<int, int>排序

set<pair<int, int> > set_pair;
for(int i=0; i<10; i++){set_pair.insert(pair<int, int>(i, i%3));
}
for(set<pair<int, int> >::iterator iter=set_pair.begin(); iter!=set_pair.end(); iter++){cout<<"("<<iter->first<<","<<iter->second<<") ";
}
cout<<endl;

输出为:

(0,0) (1,1) (2,2) (3,0) (4,1) (5,2) (6,0) (7,1) (8,2) (9,0)

2.使用less、greater排序

使用less:

set<pair<int, int>, less<pair<int, int>> > set_pair_less;
for(int i=0; i<10; i++){set_pair_less.insert(pair<int, int>(i, i%3));
}
for(set<pair<int, int>, less<pair<int, int>> >::iterator iter=set_pair_less.begin(); iter!=set_pair_less.end(); iter++){cout<<"("<<iter->first<<","<<iter->second<<") ";
}
cout<<endl;

输出为:

(0,0) (1,1) (2,2) (3,0) (4,1) (5,2) (6,0) (7,1) (8,2) (9,0)

使用greater:

set<pair<int, int>, greater<pair<int, int>> > set_pair_greater;
for(int i=0; i<10; i++){set_pair_greater.insert(pair<int, int>(i, i%3));
}
for(set<pair<int, int>, greater<pair<int, int>> >::iterator iter=set_pair_greater.begin(); iter!=set_pair_greater.end(); iter++){cout<<"("<<iter->first<<","<<iter->second<<") ";
}
cout<<endl;

输出为:

(9,0) (8,2) (7,1) (6,0) (5,2) (4,1) (3,0) (2,2) (1,1) (0,0)

使用less<>、greater<>模板对pair< int , int >排序时,先比较pair的第一个元素,如果第一个元素相等再比较第二个元素。

3.自定义排序

例如,我们使用pair<char, int>记录字符串中字符的顺序时(实际上使用map<char, int>容器记录会更方便),希望set中的字符按照频率升序排列(频率相同时,顺序不做要求),几种自定义set排序的代码如下:

#include <set>
#include <iostream>
#include <vector>using namespace std;class Cmp {public:// 重载 () 操作符// 参数必须加上const限定符bool operator()(const pair<char, int>& a, const pair<char, int>& b) const {return a.second == b.second ? (a.first < b.first) : (a.second < b.second);}
};
int main() {string str = "icaneatglass";vector<int> vec(26, 0);for (int i = 0; i < str.length(); i++) {vec[str[i] - 'a'] ++;}// 使用仿函数自定义set排序set<pair<char, int>, Cmp> set_pair_functor;// 使用lambda表达式自定义排序auto cmp = [](const pair<char, int>& a, const pair<char, int>& b) {return a.second == b.second ? (a.first < b.first) : (a.second < b.second);};set<pair<char, int>, decltype(cmp)> set_pair_lambda(cmp);// 插入数据for (int i = 0; i < 26; i++) {if (vec[i] != 0) {set_pair_functor.insert(pair<char, int>((char)('a' + i), vec[i]));set_pair_lambda.insert(pair<char, int>((char)('a' + i), vec[i]));}}// 输出for (auto it : set_pair_functor) {cout << "(" << it.first << "," << it.second << ")";}cout << endl;for (auto it : set_pair_lambda) {cout << "(" << it.first << "," << it.second << ")";}cout << endl;return 0;
}

输出为:

(c,1)(e,1)(g,1)(i,1)(l,1)(n,1)(t,1)(s,2)(a,3)
(c,1)(e,1)(g,1)(i,1)(l,1)(n,1)(t,1)(s,2)(a,3)

需要注意的是,尽管排序时我们只需要考虑pair< char, int>中的第二个参数,频率(int);不需要考虑第一个参数,字符(char)。但是在仿函数Cmp的()运算符重载中,也必须进行字符比较。
如果写成如下(下面的代码是错误的):

class Cmp{public:bool operator()(const pair<char, int> &a, const pair<char, int> &b) const{return a.second<b.second;}
};
// 其他部分代码都相同
...

最终的输出为:

(c,1) (s,2) (a,3)

这是因为:前面已经提到set中只会 store unique elements,即对于"相等"的元素set中只存储一个。而set中用Cmp类来判断两个元素是否equal。假如两个元素a和b,Cmp(a,b)返回false,Cmp(b,a)也返回false,那么就认为a和b相等。假如a和b的second(在本例中代表字符的频率)相等,那么set会只存储最后插入的元素,这就导致最终set中只会存储second(字符的频率)不同的元素。

[STL]set存储pair并自定义排序相关推荐

  1. 优先队列 以及 sort对 pari 的自定义排序

    优先队列对pair的自定义排序 #include<iostream> #include<queue> using namespace std; struct cmp{bool ...

  2. c++ map是有序还是无序的_C++ STL中Map的按Key排序和按Value排序

    map是用来存放键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行存储就是个不错的选择. 我们这样定义 ...

  3. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行 ...

  4. java hashmap 无序,【Java】HashMap自定义排序

    HashMap中的对象根据成员进行自定义排序 Map是Java中最常用的存储对象的集合类之一,存储在HashMap中的对象在取出时是无序的,下文以示例介绍了如果对HashMap中存储的对象根据成员进行 ...

  5. DEV控件自定义排序实现

    一般的控件或者组件都支持按照某一列进行排序.但是,这种排序是根据数据源里的数据默认按照降序或升序排序的,同时这样的排序与字段的类型有关. 假设现在字段的类型是字符串类型 ,但是,存储的数据时数字加一些 ...

  6. Java比较同一map是否相同_Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等...

    /* Map集合:该集合存储键值对.一对一对往里存.而且要保证键的唯一性. Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低.基本已废 ...

  7. 优先队列如何按照pair 的第二关键字排序(对比vector按照pair第二关键字排序)

    按照pair的第二关键字排序需要自定义,需要注意的是优先队列priority_queue的重载和vector等是相反的,即 vector中是从小到大,到了优先队列是从大到小.当然,cmp的写法也有些不 ...

  8. stl中各种容器的自定义比较函数

    class elem { public:elem();elem(int aa):a(aa){} public:int a;int getA(){return a;} };class elem1 { p ...

  9. MySQL自定义排序函数FIELD()

    转载自:https://blog.csdn.net/lxz3000/article/details/6173873 MySQL可以通过field()函数自定义排序 格式: field(value,st ...

最新文章

  1. 数据结构——基本概念
  2. android源码分析之JNI调用与回调
  3. boost::process::search_path相关的测试程序
  4. ccf魔数c语言,ccf 201609-4 交通规划
  5. 软件开发实践的24条军规
  6. 求相似三角形的几种方法,相似三角形算法有哪些
  7. Wincc使用.net控件将锐浪报表Grid++Report6嵌入
  8. 中级软件设计师JAVA
  9. 权重股启动意味着什么
  10. Google 按图搜索的原理
  11. 最新十大透支健康行业(2019年版)
  12. java虚拟机之java堆
  13. 干货,主流大数据技术总结
  14. QT5.7操作word
  15. 获取data-*属性值
  16. 星际争霸,FF反作弊对战平台
  17. 圣斗士星矢-我至爱的动画片-Phoenix
  18. 智能绿化灌溉系统解决方案
  19. palindrome-partitioning
  20. 微软ODBC服务器驱动,系统要求、安装和驱动程序文件

热门文章

  1. Kotlin学习——简单运用协程网络下载图片并更新到UI
  2. 关于C++传递数组时初始化注意事项(允悲)
  3. 电子器件系列31:ULN2003 芯片详解
  4. matlab语言及应用期末试卷,《MATLAB语言及应用》期末考试试题
  5. 怎么做一名合格的测试工程师
  6. 金三银四铜五铁六,面试得做好这个准备
  7. 获取任意时间前几分钟前的时间点的方法
  8. 2020年中国嵌入式软件市场现状分析,国家政策大力支持行业发展「图」
  9. RK3399 / AR9201 / Tegra K1 /hi3559A / RV1126对比
  10. 20180102189刘钰