STL之map中排序方式的重载

版权声明:个人做题总结专用~ https://blog.csdn.net/tb_youth/article/details/89602706

1.map中的数据默认是按key值字典序排
栗子:

#include <iostream>
#include <map>
using namespace std;
//typedef pair<char,int>PAIR;
int main()
{
    map<char,int>mp;
    mp.insert(make_pair('b',1));//插入数据方式1
    mp['a'] = 2;//插入数据方式2
    mp.insert(make_pair('A',3));
    for(map<char,int>::iterator it = mp.begin(); it!=mp.end(); it++)
    {
        cout<<it->first<<" "<<it->second<<endl;
    }
    return 0;
}

运行结果:
在这里插入图片描述

#include <iostream>
#include <string.h>
#include <map>
using namespace std;
int main()
{
    map<string,int>mp;
    mp.insert(make_pair("bab",1));
    mp["abb"] = 2;
    mp.insert(make_pair("Adfd",3));
    mp["baaa"] = 4;
    mp["gfgggh"] = 5;
    for(map<string,int>::iterator it = mp.begin(); it!=mp.end(); it++)
    {
        cout<<it->first<<" "<<it->second<<endl;
    }
    return 0;
}

在这里插入图片描述
但是现在如果key值为一个很大的数字(要用字符串表示),我们希望让它按数字从小到到排序,不对map重载能行吗?
下面先来看个题目:
题目背景
宇宙总统竞选

题目描述
地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。

输入输出格式
输入格式:
president.in

第一行为一个整数n,代表竞选总统的人数。

接下来有n行,分别为第一个候选人到第n个候选人的票数。

输出格式:
president.out

共两行,第一行是一个整数m,为当上总统的人的号数。

第二行是当上总统的人的选票。

输入输出样例
输入样例#1:

5
98765
12365
87954
1022356
985678

输出样例#1:

4
1022356

说明
票数可能会很大,可能会到100位数字。

n<=20
这个题目我想用map来做
不重载行吗?
WA code:

#include <iostream>
#include <map>
#include <string.h>
using namespace std;
map<string,int>mp;
int main()
{
    int n;
    cin>>n;
    string s;
    for(int i = 1; i <= n; i++)
    {
       cin>>s;
       mp[s] = i;
    }
    map<string,int>::iterator it = mp.begin();
    cout<<it->second<<'\n'<<it->first<<endl;
    return 0;
}

样例测试结果:
在这里插入图片描述
上面这份代码样例是能过的,但是看下面这组数据:

7
6791385765449865851630484098561093867193
6791385765405861305476138956183659819548
6791385765448765481033867082657092835470
6791385765476183659186548165418634013875
6791385765413054861086540816508058173710
6365470813654816508136547081654108365108
36571811836547138541

测试结果却是不正确的:

在这里插入图片描述
可以看出,不作重载无法达到我们的目标(key值为一个很长的数字串,让它从小到大排序(或从大到小))。
一开始用map没重载来做上那个问题,WA。原因是我误认为字典序可以将一个很长的数字串从小到大来排序。
那么我想让map来实现大数从小到大(或从大到小)排序该怎么办?当然就是对key进行重载咯。
对key重载前先了解一下STL中map的模板:

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

class Compare=less可以看出map这里指定less作为其默认比较函数(对象)
所以重载比较函数

#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef pair<string,int>PAIR;
ostream& operator<<(ostream& out,const PAIR& p){//重载输出流
    return out<<p.second<<'\n'<<p.first;
}
struct cmp{//重载map的key值排序方式
    bool operator()(const string& x,const string& y){
        if(x.length()==y.length())//一样长的话,字符串比较,大的数更大
            return x > y;
        return x.length()>y.length();//更长的数字更大
    }
};
map<string,int,cmp>mp;
int main()
{
    int n;
    cin>>n;
    string s;
    for(int i = 1; i <= n; i++)
    {
        cin>>s;
        mp.insert(make_pair(s,i));//map[s] = i;
    }
    map<string,int,cmp>::iterator it = mp.begin();
    cout<<*it<<endl;
    return 0;
}

运行结果:
在这里插入图片描述
2.如果想让`map按value值排序怎么办?
比如用map实现,想让学生的按成绩升序排
直接上代码:

#include <bits/stdc++.h>
using namespace std;
typedef pair<string,int> PAIR;
//比较函数(重载方式一)
bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {
  return lhs.second < rhs.second;
}
/*
//函数对象(重载方式二)
struct CmpByValue {
  bool operator()(const PAIR& lhs, const PAIR& rhs) {
    return lhs.second < rhs.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));
 //把map中元素转存到vector中
  vector<PAIR> name_score_vec(name_score_map.begin(), name_score_map.end());
  //sort(name_score_vec.begin(), name_score_vec.end(), CmpByValue());
  sort(name_score_vec.begin(), name_score_vec.end(), cmp_by_value);
  for (int i = 0; i < name_score_vec.size(); ++i) {
    cout << name_score_vec[i].first<<' '<<name_score_vec[i].second << endl;
  }
  return 0;
}

运行结果:
在这里插入图片描述
更详细的请参考博客:
https://blog.csdn.net/iicy266/article/details/11906189

猜你喜欢

转载自blog.csdn.net/tb_youth/article/details/89602706