[STL]set存储pair并自定义排序
一、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模板类有三个参数:
- T:set容器中的元素类型。
- Compare:比较类,定义容器中元素排序,缺省为less< T >。
- 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并自定义排序相关推荐
- 优先队列 以及 sort对 pari 的自定义排序
优先队列对pair的自定义排序 #include<iostream> #include<queue> using namespace std; struct cmp{bool ...
- c++ map是有序还是无序的_C++ STL中Map的按Key排序和按Value排序
map是用来存放键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行存储就是个不错的选择. 我们这样定义 ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行 ...
- java hashmap 无序,【Java】HashMap自定义排序
HashMap中的对象根据成员进行自定义排序 Map是Java中最常用的存储对象的集合类之一,存储在HashMap中的对象在取出时是无序的,下文以示例介绍了如果对HashMap中存储的对象根据成员进行 ...
- DEV控件自定义排序实现
一般的控件或者组件都支持按照某一列进行排序.但是,这种排序是根据数据源里的数据默认按照降序或升序排序的,同时这样的排序与字段的类型有关. 假设现在字段的类型是字符串类型 ,但是,存储的数据时数字加一些 ...
- Java比较同一map是否相同_Java 中HashTable、HashMap、TreeMap三者区别,以及自定义对象是否相同比较,自定义排序等...
/* Map集合:该集合存储键值对.一对一对往里存.而且要保证键的唯一性. Map |--Hashtable:底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低.基本已废 ...
- 优先队列如何按照pair 的第二关键字排序(对比vector按照pair第二关键字排序)
按照pair的第二关键字排序需要自定义,需要注意的是优先队列priority_queue的重载和vector等是相反的,即 vector中是从小到大,到了优先队列是从大到小.当然,cmp的写法也有些不 ...
- stl中各种容器的自定义比较函数
class elem { public:elem();elem(int aa):a(aa){} public:int a;int getA(){return a;} };class elem1 { p ...
- MySQL自定义排序函数FIELD()
转载自:https://blog.csdn.net/lxz3000/article/details/6173873 MySQL可以通过field()函数自定义排序 格式: field(value,st ...
最新文章
- 数据结构——基本概念
- android源码分析之JNI调用与回调
- boost::process::search_path相关的测试程序
- ccf魔数c语言,ccf 201609-4 交通规划
- 软件开发实践的24条军规
- 求相似三角形的几种方法,相似三角形算法有哪些
- Wincc使用.net控件将锐浪报表Grid++Report6嵌入
- 中级软件设计师JAVA
- 权重股启动意味着什么
- Google 按图搜索的原理
- 最新十大透支健康行业(2019年版)
- java虚拟机之java堆
- 干货,主流大数据技术总结
- QT5.7操作word
- 获取data-*属性值
- 星际争霸,FF反作弊对战平台
- 圣斗士星矢-我至爱的动画片-Phoenix
- 智能绿化灌溉系统解决方案
- palindrome-partitioning
- 微软ODBC服务器驱动,系统要求、安装和驱动程序文件