c++对map进行排序

来源:互联网 发布:旅行社信息管理数据库 编辑:程序博客网 时间:2024/04/28 22:14

原文地址:http://blog.csdn.net/jiejinquanil/article/details/51544145

最近在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)这一题为背景例子进行编程说明。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //按Key排序  
  2. #include<iostream>  
  3. #include<vector>  
  4. #include<map>  
  5. #include<iomanip>  
  6.   
  7. using namespace std;    
  8.   
  9. int main()  
  10. {  
  11.     double N,maxneed,tm,ts;  
  12.     cin>>N>>maxneed;  
  13.     vector<double> vm,vs,vp;//vm是总量,vs是总销售额,vp是价格  
  14.     for(int i = 1;i<=N;++i)  
  15.     {  
  16.         cin>>tm;  
  17.         vm.push_back(tm);  
  18.     }  
  19.     for(int i = 1;i<=N;++i)  
  20.     {  
  21.         cin>>ts;  
  22.         vs.push_back(ts);  
  23.     }  
  24.     for(int i = 0;i<N;++i)  
  25.         vp.push_back(vs[i]/vm[i]);  
  26.   
  27.     map<double,double> m;  
  28.     for(int i = 0;i<N;++i)  
  29.         m.insert(make_pair(vp[i],vs[i]));//插入后自动按Key值进行排序  
  30.     cout<<"按Key排序结果:"<<endl;  
  31.     for(map<double,double>::iterator it=m.begin();it!=m.end();++it)  
  32.         cout<<it->first<<" "<<it->second<<endl;  
  33.   
  34.     system("pause");  
  35.     return 0;  
  36. }  

结果如下:


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

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

       另举一例进行说明:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<map>    
  3. #include<string>    
  4.     
  5. using namespace std;    
  6.     
  7. typedef pair<string, int> PAIR;    
  8.     
  9. ostream& operator<<(ostream& out, const PAIR& p)   
  10. {    
  11.     return out << p.first << "\t" << p.second;    
  12. }    
  13.     
  14. int main()   
  15. {    
  16.     map<string, int> name_score_map;    
  17.     name_score_map["LiMin"] = 90;     
  18.     name_score_map["ZiLinMi"] = 79;     
  19.     name_score_map["BoB"] = 92;     
  20.     name_score_map.insert(make_pair("Bing",99));    
  21.     name_score_map.insert(make_pair("Albert",86));    
  22.     for (map<string, int>::iterator iter = name_score_map.begin();    
  23.         iter != name_score_map.end();    
  24.         ++iter) {    
  25.         cout << *iter << endl;    
  26.     }    
  27.     system("pause");  
  28.     return 0;    
  29.  }   
结果如下:


上面的按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按照一定的规则排序即可。这样的方法对值一样的情况也能够使用。具体代码如下:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //功能:输入单词,统计单词出现次数并按照单词出现次数从多到少排序    
  2. #include <iostream>  
  3. #include <cstdlib>    
  4. #include <map>    
  5. #include <vector>    
  6. #include <string>    
  7. #include <algorithm>    
  8.   
  9. using namespace std;  
  10.      
  11. int cmp(const pair<string, int>& x, const pair<string, int>& y)    
  12. {    
  13.     return x.second > y.second;    
  14. }    
  15.      
  16. void sortMapByValue(map<string, int>& tMap,vector<pair<string, int> >& tVector)    
  17. {    
  18.     for (map<string, int>::iterator curr = tMap.begin(); curr != tMap.end(); curr++)     
  19.         tVector.push_back(make_pair(curr->first, curr->second));      
  20.      
  21.     sort(tVector.begin(), tVector.end(), cmp);    
  22. }    
  23. int main()    
  24. {    
  25.     map<string, int> tMap;    
  26.     string word;    
  27.     while (cin >> word)    
  28.     {    
  29.         pair<map<string,int>::iterator,bool> ret = tMap.insert(make_pair(word, 1));    
  30.         if (!ret.second)    
  31.             ++ret.first->second;    
  32.     }     
  33.      
  34.     vector<pair<string,int>> tVector;    
  35.     sortMapByValue(tMap,tVector);    
  36.     for(int i=0;i<tVector.size();i++)    
  37.         cout<<tVector[i].first<<": "<<tVector[i].second<<endl;    
  38.      
  39.     system("pause");    
  40.     return 0;    
  41. }    

结果如下:



参考资料

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

C++STL之map学习

STL中map按值(value)排序

对map集合进行排序

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

如何禁止STL map 自动排序

0 0
原创粉丝点击