C++ map根据value进行排序,以及sort中cmp比较器的实现

这篇文章根据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;
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值