map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value。假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map来进行存储就是个不错的选择。 我们这样定义,map<string, int>,其中学生姓名用string类型,作为Key;该学生的成绩用int类型,作为value。这样一来,我们可以根据学生姓名快速的查找到他的成绩。

但是,我们除了希望能够查询某个学生的成绩,或许还想看看整体的情况。我们想把所有同学和他相应的成绩都输出来,并且按照我们想要的顺序进行输出:比如按照学生姓名的顺序进行输出,或者按照学生成绩的高低进行输出。换句话说,我们希望能够对map进行按Key排序或按Value排序,然后按序输出其键值对的内容。

其实,为了实现快速查找,map内部本身就是按序存储的(比如红黑树)。在我们插入<key, value>键值对时,就会按照key的大小顺序进行存储。这也是作为key的类型必须能够进行<运算比较的原因。现在我们用string类型作为key,因此,我们的存储就是按学生姓名的字典排序储存的。我们都知道在使用map的时候是按照key从小到大排序的,并不是说map只能这样排序只不过从小到大是其默认的排序方式罢了。我们完全可以指定其他的排序方式。

一、C++ STL中Map的按Key从大到小的排序

map是stl里面的一个模板类,现在我们来看下map的定义:

template < class Key, class T, class Compare = less<Key>,class Allocator = allocator<pair<const Key,T> > > class map;

它有四个参数,其中我们比较熟悉的有两个: Key 和 Value。第四个是 Allocator,用来定义存储分配模型的,此处我们不作介绍。

现在我们重点看下第三个参数: class Compare = less<Key>

这也是一个class类型的,而且提供了默认值 less<Key>。 就是这个默认的less<key>决定了从下到大的排序方式。

less是stl里面的一个函数对象,那么什么是函数对象呢?

所谓的函数对象:即调用操作符的类,其对象常称为函数对象(function object),它们是行为类似函数的对象。表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个 类,其实质是对operator()操作符的重载。

现在我们来看一下less的实现:

template <class T> struct less : binary_function <T,T,bool> {bool operator() (const T& x, const T& y) const{return x<y;}
};

它是一个带模板的struct,里面仅仅对()运算符进行了重载,实现很简单,但用起来很方便,这就是函数对象的优点所在。stl中还为四则运算等常见运算定义了这样的函数对象,与less相对的还有greater:

template <class T> struct greater : binary_function <T,T,bool> {bool operator() (const T& x, const T& y) const{return x>y;}
};

map这里指定less作为其默认比较函数(对象),所以我们通常如果不自己指定Compare,map中键值对就会按照Key的less顺序进行组织存储,因此我们就看到了上面代码输出结果是按照学生姓名的字典顺序输出的,即string的less序列。

我们可以在定义map的时候,指定它的第三个参数Compare,比如我们把默认的less指定为greater。如下所示即可更改排序方式为从大到小。map<string,string,greater<string>> mymap;

#include<iostream>
#include <map>
#include <string>
using namespace std;
int main(){//map<string,string> mymap;map<string,string,greater<string>> mymap;mymap["a"]="student1";mymap["b"]="student2";mymap["c"]="student3";  mymap["d"]="student4"; for(auto iter=mymap.begin();iter!=mymap.end();++iter){cout<<(*iter).first<<"->"<<(*iter).second<<endl;}return 0;
}

如下所示程序的输出为:

二、C++ STL中指定Map的排序方式

如何实现map按照自定义的方式进行排序呢?例如,我想按照学生的名字的长度进行排序,如何来做?见如下程序实例。

#include<iostream>
#include <map>
#include <string>
using namespace std;
//这里不用吧Compare定义为模板,直接指定他的参数为string就好了。
struct CmpByKeyLength{bool operator()(const string& k1,const string& k2){return k1.length()<k2.length();}
};
int main(){//map<string,string> mymap;//map<string,int> mymap;map<string,int,CmpByKeyLength> mymap;mymap["b"]=90;mymap["aa"]=92;mymap["bbb"]=98; mymap["aaaa"]=90;    for(auto iter=mymap.begin();iter!=mymap.end();++iter){cout<<(*iter).first<<"->"<<(*iter).second<<endl;}return 0;
}

程序执行结果如下:

三、key是结构体的Map排序

见如下程序实例:

#include<iostream>
#include <map>
#include <string>using namespace std;struct stu_info{int id;string name;bool operator<(stu_info const& r) const{if(id<r.id) return true;if(id==r.id) return name.compare(r.name)<0;return false;}
};int main(){stu_info info1;map<stu_info,int> mymap;info1.id=2;info1.name="yangmi";mymap[info1]=90;info1.id=2;info1.name="tongliya";mymap[info1]=99;for(auto iter=mymap.begin();iter!=mymap.end();++iter){
//      cout<<(*iter).first<<"->"<<(*iter).second<<endl;cout<<"id="<<iter->first.id;cout<<",name="<<iter->first.name;cout<<",score="<<iter->second<<endl;}return 0;
}

程序执行结果如下:

四、将map按value排序

实现思路:借助vector。先把map的元素按照pair形式插入到vector中,再对vector进行排序(用一个新写的比较函数),这样就可以实现按照map的value排序了。

知识点一:将map中的pair元素放入vector中去

vector<pair<string,int>> myvec(mymap.begin(),mymap.end());

示例程序如下:

//演示按照value对map进行排序
#include<iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
/*这个语句会出错,奇怪???*/
//typedef pair<string,int> PAIR;
using namespace std;
//以下两个cmp函数任一均可用于sort
//bool cmp(const PAIR& pair1,const PAIR& pair2){
bool cmp(const pair<string,int>& pair1,const pair<string,int>& pair2){return pair1.second<pair2.second;
}int main(){map<string,int> mymap;mymap["tongliya"]=99;mymap["yangmi"]=90;mymap["dongjie"]=88;mymap["liuyifei"]=92;//vector<PAIR> myvec(mymap.begin(),mymap.end());vector<pair<string,int>> myvec(mymap.begin(),mymap.end());sort(myvec.begin(),myvec.end(),cmp);for(auto iter=myvec.begin();iter!=myvec.end();++iter){cout<<"name="<<iter->first;cout<<",score="<<iter->second<<endl;}return 0;
}

运行结果如下:

注:typedef pair<string,int> PAIR;语句会报错“‘pair’不是一个类型”,有点奇怪。

关于map的几种非常规排序相关推荐

  1. 来自谷歌大脑的SpineNet:一种非常规的主干结构

    参考来自谷歌大脑的SpineNet:一种非常规的主干结构 - 云+社区 - 腾讯云 由于编码器部分的解码器结构的分辨率不断降低,分类问题得到了很好的解决.然而,这种架构不能有效地生成用于目标检测(同时 ...

  2. java中map嵌套map_java中遍历MAP,嵌套map的几种方法

    java中遍历MAP的几种方法 Map map=new HashMap(); map.put("username", "qq"); map.put(" ...

  3. 三种基本排序的实现及其效率对比:冒泡排序、选择排序和插入排序

    1 public class ThreeTypesOfBaseSort { 2 // ========================== 三种基本排序的效率对比 ================== ...

  4. 3分钟快速实现:9种经典排序算法的可视化

    作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017) 最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 不知道 ...

  5. c++ map iterator 获取key_前K个高频的元素衍生之Map的Value与Key排序

    前言 本篇文章总结来自九月份的每日一题 347-前K个高频的元素 思考 对于系列的题目就是计算利用到Hash表的属性的Key与Value的双属性,能够满足我们后面计算对于每一个元素出现的频率的同时还能 ...

  6. 3min利用Python实现9种经典排序算法可视化!(附源代码)

    来源:恋习Python 本文附视频,建议收藏. 本文为你分享实现9种经典排序算法可视化的方法,3分钟即可实现. [导 读]近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感 ...

  7. BCH到底该采用哪种交易排序规则?

    ​​目前BCH在选取哪种交易排序方面依旧没有达成共识.其实针对BCH到底该采用什么交易排序规则这一问题完全可以通过分析对比进行决定. 针对这个问题应该分几个步骤进行思考. 1.目前的TTOR需不需要被 ...

  8. 算法:三种简单排序算法

    排序算法比較常见的有:冒泡排序.简单选择排序.直接插入排序:希尔排序.堆排序.归并排序和高速排序算法等. 今天先学习一下前面三种比較简单的算法.排序的相关概念: ①排序的稳定性:两个或多个元素相等.排 ...

  9. java map 迭代遍历_java 遍历Map的四种方式

    java 遍历Map的四种方式 CreationTime--2018年7月16日16点15分 Author:Marydon 一.迭代key&value 第一种方式:迭代entrySet 1.方 ...

  10. PHP实现四种基本排序算法

    ###PHP实现四种基本排序算法 前提:分别用冒泡排序法, 快速排序法, 选择排序法, 插入排序法将下面数组中的值按照从小到大的顺序进行排序. (1)冒泡算法 $arr=array(1,43,54,6 ...

最新文章

  1. JESD204B概述
  2. Cortex-M3中的存储器映射
  3. 【Git】认识各种开源协议及其关系
  4. 企业移动应用平台:走进SAP SUP的世界
  5. 构建LAMP平台(一)(软件版本:httpd-2.4.16,php-5.6.12,mysql-5.6.26)
  6. 如何用ELK搭建TB级的日志监控系统?
  7. puml绘制思维导图_强推:9款超好用思维导图APP
  8. usb不能识别的解决方案
  9. DSP芯片的基本结构
  10. 新浪云生成互联网页面及域名
  11. 支付宝信用贷豪掷38亿抢客,微粒贷不怂
  12. 关于免费申请6位QQ的真相
  13. 计算机大赛的英语怎么说,最全英语奖项 比赛名称翻译.doc
  14. 【其它】颜色的知识--亮度、色相、饱和度、对比度
  15. 10种食物让女性养颜排毒又减肥(图)
  16. 关于c#的书籍下载网站和地址
  17. 前端模块化、组件化开发
  18. java连不上sqlserver_java和SQL连接不上——解决步骤
  19. 小指数rsa 多线程版writeup
  20. MacBook好用的电脑垃圾清理管家工具CleanMyMac X

热门文章

  1. Win10装Ubuntu双系统步骤做法
  2. Ubuntu学习 history
  3. Android 去除头部标题
  4. spring boot发送其他邮件
  5. 微信小程序-携带参数的二维码条形码生成
  6. 使用Jmeter性能测试注意点
  7. 你能识别这些科技公司的真假logo吗?
  8. poj1083 解题报告(poj 1083 analysis report)
  9. 值类型、引用类型 再次理解
  10. C++ 任意进制相互转换