c++对map进行排序

          最近在PAT刷题,其中一道题月饼 (25)需要用到对价格进行排序,但是排序后要用到价格对应的总售价。因而可以考虑用关联容器进行求解,map是比较合适这题的数据结构。

        map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value。关于map的详细定义及用法可以见C++STL之map学习。假如存储学生和其成绩,我们用map来进行存储就是个不错的选择。 我们这样定义map<string, int>,其中学生姓名用string类型,作为Key;该学生的成绩用int类型,作为value。我们可以根据学生姓名快速的查找到他的成绩。另一方面,如果我们想把所有同学和他相应的成绩都输出来,并且按照我们想要的顺序进行输出:比如按照学生姓名的顺序进行输出,或者按照学生成绩的高低进行输出。换句话说,我们希望能够对map进行按Key排序或按Value排序。本文对这两种排序进行一个简单的总结。


一、按Key排序

       我们知道,map内部本身就是按序存储的(比如红黑树),这样方便实现快速查找。在我们插入<key, value>键值对时,map就会自动按照key的大小顺序进行存储。因而作为key的类型必须能够进行大小运算的比较。比如int、double、string、char等类型。以月饼 (25)这一题为背景例子进行编程说明。

//按Key排序
#include<iostream>
#include<vector>
#include<map>
#include<iomanip>

using namespace std;  

int main()
{
	double N,maxneed,tm,ts;
	cin>>N>>maxneed;
	vector<double> vm,vs,vp;//vm是总量,vs是总销售额,vp是价格
	for(int i = 1;i<=N;++i)
	{
		cin>>tm;
		vm.push_back(tm);
	}
	for(int i = 1;i<=N;++i)
	{
		cin>>ts;
		vs.push_back(ts);
	}
	for(int i = 0;i<N;++i)
		vp.push_back(vs[i]/vm[i]);

	map<double,double> m;
	for(int i = 0;i<N;++i)
		m.insert(make_pair(vp[i],vs[i]));//插入后自动按Key值进行排序
	cout<<"按Key排序结果:"<<endl;
	for(map<double,double>::iterator it=m.begin();it!=m.end();++it)
		cout<<it->first<<" "<<it->second<<endl;

	system("pause");
	return 0;
}

结果如下:


       从结果可以看到未对map进行任何操作,它按照Key值自动进行了排序。

       具体到月饼 (25)这一题上,详细分析可以见另外一篇博客PAT上面一道关于“月饼”的题目的解法

       另举一例进行说明:

#include<iostream>
#include<map>  
#include<string>  
  
using namespace std;  
  
typedef pair<string, int> PAIR;  
  
ostream& operator<<(ostream& out, const PAIR& p) 
{  
	return out << p.first << "\t" << p.second;  
}  
  
int main() 
{  
	map<string, int> name_score_map;  
	name_score_map["LiMin"] = 90;   
    name_score_map["ZiLinMi"] = 79;   
    name_score_map["BoB"] = 92;   
    name_score_map.insert(make_pair("Bing",99));  
    name_score_map.insert(make_pair("Albert",86));  
    for (map<string, int>::iterator iter = name_score_map.begin();  
		iter != name_score_map.end();  
		++iter) {  
		cout << *iter << endl;  
	}  
	system("pause");
	return 0;  
 } 
结果如下:


上面的按key值排序有个缺点:即当插入的有多个相等的值时,由于key的唯一性,会只保留一个。因此月饼 (25)这一题不适合用按key进行排序求解(因为不排斥某两种月饼的价格相等)。


二、按Value排序

        如何实现Map的按Value排序呢?

        第一反应是利用STL中提供的sort算法实现,这个想法是好的,不幸的是,sort算法有个限制,利用sort算法只能对序列容器进行排序,就是线性的(如vector,list,deque)。map是一个集合容器,它里面存储的元素是pair,但是它不是线性存储的(像红黑树),所以利用sort不能直接和map结合进行排序。因而可以采用一些其它的思路,总结如下:


思路1:可以考虑将value作为key值进行自动排序。

思路2:可以把map中的key值和value值分别转存到一个pair类型的vector中,在对vector按照一定的规则排序即可。这样的方法对值一样的情况也能够使用。具体代码如下:

//功能:输入单词,统计单词出现次数并按照单词出现次数从多到少排序  
#include <iostream>
#include <cstdlib>  
#include <map>  
#include <vector>  
#include <string>  
#include <algorithm>  

using namespace std;
   
int cmp(const pair<string, int>& x, const pair<string, int>& y)  
{  
	return x.second > y.second;  
}  
   
void sortMapByValue(map<string, int>& tMap,vector<pair<string, int> >& tVector)  
{  
	for (map<string, int>::iterator curr = tMap.begin(); curr != tMap.end(); curr++)   
		tVector.push_back(make_pair(curr->first, curr->second));    
   
	sort(tVector.begin(), tVector.end(), cmp);  
}  
int main()  
{  
	map<string, int> tMap;  
	string word;  
	while (cin >> word)  
	{  
		pair<map<string,int>::iterator,bool> ret = tMap.insert(make_pair(word, 1));  
		if (!ret.second)  
			++ret.first->second;  
	}   
   
	vector<pair<string,int>> tVector;  
	sortMapByValue(tMap,tVector);  
	for(int i=0;i<tVector.size();i++)  
		cout<<tVector[i].first<<": "<<tVector[i].second<<endl;  
   
	system("pause");  
	return 0;  
}  

结果如下:



参考资料

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

C++STL之map学习

STL中map按值(value)排序

对map集合进行排序

STL容器(三)——对map排序

如何禁止STL map 自动排序

  • 23
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值