C++自定义比较函数外部数据结构使用问题:排序结果不符
问题:自定义比较类实现排序,结果不符合预期?
需求:对数字数组按出现频率升序排序,频率相同时按数值降序排序。
我用unordered_map统计数字频率,通过类的operator()自定义比较函数实现排序,代码如下:
class Solution { public: unordered_map<int,int> map; bool operator ()(const int &a,const int &b){ if(map[a]==map[b]) return a>b; return map[a]<map[b]; } vector<int> frequencySort(vector<int>& nums) { vector<int> answer; for(auto num:nums) map[num]++; sort(nums.begin(),nums.end(),Solution()); return nums; } };
但输入nums = [1,1,2,2,2,3]时,输出为[3,2,2,2,1,1],不符合预期的[3,1,1,2,2,2]。
而用lambda表达式实现自定义排序就能得到正确结果,代码如下:
sort(nums.begin(),nums.end(),[&](int a, int b) { if (map[a] == map[b]) { return a > b; } return map[a] < map[b]; });
明明逻辑一致,为什么我的类实现会出错?
错误原因
核心问题出在sort(nums.begin(),nums.end(),Solution());这一行:你在这里新建了一个全新的Solution对象,这个新对象的map是空的!
你之前在frequencySort函数里统计的频率,是存在当前this指针指向的对象的map里,而传给sort的新Solution()实例,它的map没有任何统计数据。当访问unordered_map中不存在的键时,会自动插入该键并赋值默认值0,所以比较时map[a]和map[b]始终相等(都是0),排序逻辑就退化成了按数值降序排列,这就是你得到错误结果的原因。
而lambda表达式用[&]捕获了当前函数作用域的变量(也就是当前对象的map),所以能正确获取到统计好的频率数据,自然排序正确。
修正方法
只需要把传给sort的参数改成当前对象*this,而不是新建一个Solution实例,这样比较函数就能使用已经统计好频率的map了:
class Solution { public: unordered_map<int,int> map; bool operator ()(const int &a,const int &b){ if(map[a]==map[b]) return a>b; return map[a]<map[b]; } vector<int> frequencySort(vector<int>& nums) { for(auto num:nums) map[num]++; sort(nums.begin(), nums.end(), *this); // 传入当前对象,而非新建实例 return nums; } };
内容的提问来源于stack exchange,提问作者Bhavya Patel
相关产品推荐
相关产品推荐

