这篇文章根据leetcode中的第451题:根据字符出现频率排序
链接:leetcode 451 根据字符出现频率排序
来实现map的根据value值进行排序
看了网上很多内容,整理下:
一、按Key排序
map内部本身按序存储的(比如红黑树),这样方便实现快速查找。在我们插入
<key, value>键值对时,map就会自动按照key的大小顺序进行存储。因而作为key的
类型必须能够进行大小运算的比较。比如int、double、string、char等类型
二、按Value排序
利用STL中提供的sort算法实现,但是sort算法有个限制,利用sort算法只
能对序列容器进行排序,就是线性的(如vector,list,deque)。map是
一个集合容器,它里面存储的元素是pair,但是它不是线性存储的(像红黑树),
所以利用sort不能直接和map结合进行排序。这里除了将将value作为key值进
行自动排序(麻烦)外可以:
把map中的key值和value值分别转存到一个pair类型的vector中,在对vector按照一定的规则排序即可。这样的方法对值一样的情况也能够使用。
那么问题就是怎么设计sort中的比较器cmp???(我搜的很多文章都是直接写成了一个 bool cmp() 函数,但是在使用的时候遇到了问题,尤其是大部分在main()函数中使用的 )
leetcode 692题中也是用cmp实现的堆的排序规则
先来看一个错误:
error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_comp_iter<bool (Solution::*)(const std::pair<char, int>&, const std::pair<char, int>&)>*)this)-。。。
template<typename _Iterator1, typename _Iterator2>
_GLIBCXX14_CONSTEXPR
bool
operator()(_Iterator1 __it1, _Iterator2 __it2)
{ return bool(_M_comp(*__it1, *__it2)); }
};
leetcode中,也会提示sort(, , cmp) 的错误
所以想还是把cmp封装一下,
struct cmp
{
bool operator ()(const pair<char, int>& x, const pair<char, int>& y) const
{
return x.second > y.second;
}
};
当然直接在sort中写也可以,就是
sort(vec.begin(),vec.end(),[](pair<char,int> p1,pair<char,int> p2){return p1.second>p2.second;});
我这里是走了很多坑,所以记一下
下面是正确的做法代码
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
class Solution {
public:
//为什么要把自己设计的比较器定义在一个cmp结构体中,这里重载了()运算符,
//如果直接设计函数 bool cmp(const pair<char, int>& x, const pair<char, int>& y),在sort(vec.begin(),vec.end(),cmp)的时候,是不可以的(反正很多情况下我是不可以,比如 编译环境 code::blocks下,会提示上述的错误)
struct cmp
{
bool operator ()(const pair<char, int>& x, const pair<char, int>& y) const
{
return x.second > y.second;
}
};
void sortMapByValue(unordered_map<char, int>& tMap,vector<pair<char, int> >& tVector)
{
for (unordered_map<char, int>::iterator curr = tMap.begin(); curr != tMap.end(); curr++)
tVector.push_back(make_pair(curr->first, curr->second));
cmp cp; //结构体比较器
sort(tVector.begin(), tVector.end(), cp);
}
string frequencySort(string s) {
if(s == "") return "";
int n = s.size();
//通过map统计出词频
unordered_map<char,int> mp;
for(int i = 0; i < n; i++)
{
mp[s[i]]++;
}
//对map根据词频进行排序
vector<pair<char,int>> ves;
sortMapByValue(mp,ves);
string res = "";
for(auto item : ves)
res += item.first;
return res;
}
};
void Test()
{
Solution obj;
cout<<obj.frequencySort("aaaccbb");
}
int main()
{
Test();
return 0;
}