【问题标题】:How to use functor as custom comparator in priority_queue如何在priority_queue中使用函子作为自定义比较器
【发布时间】:2020-08-27 17:12:42
【问题描述】:

我正在尝试创建一个仿函数作为我的 priority_queue 的自定义比较器,它将 unordered_map 作为构造函数的参数。当我收到错误时,我不确定如何在声明 priority_queue 时调用仿函数:

"Line 22: Char 48: error: template argument for template type parameter must be a type priority_queue pq;"

   class compareWords{
        public:
        compareWords(unordered_map<string, int> &wordCounts): wordFreq(wordCounts){}
        bool operator()(string word1, string word2){
            if(wordFreq[word1] == wordFreq[word2]){
                return word1 < word2;
            }
            return wordFreq[word1] < wordFreq[word2];
        }
        private:
        unordered_map<string, int> wordFreq;
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        vector<string> result;
        unordered_map<string, int> wordFreq;
        for(int i = 0; i < words.size(); i++){
            wordFreq[words[i]]++;
        }
        priority_queue<string, vector<string>, compareWords(wordFreq)> pq;
        for(auto& item: wordFreq){
            pq.push(item.first);
        }
        for(int i = 0; i < k; i++){
            result.push_back(pq.top());
            pq.pop();
        }
        return result;
    }

【问题讨论】:

    标签: c++ priority-queue functor


    【解决方案1】:

    TL;DR 版本:

    priority_queue<string, vector<string>, compareWords> pq(compareWords{wordFreq});
    

    我们是如何到达那里的:

    通过简单的解决方案,将比较器传递给pq的构造函数,你会遇到Most Vexing Parse

    priority_queue<string, vector<string>, compareWords> pq(compareWords(wordFreq));
                                           ^class goes here ^ object goes here     
    

    是一个函数定义。呸。通常MVP的解决方案是使用“统一初始化”

    priority_queue<string, vector<string>, compareWords> pq{compareWords(wordFreq)};
                                                           ^                      ^
    

    但这会触发priority_queue 的初始化列表构造函数。也很恶心。

    但是,我们可以在 compareWords 的构造中使用花括号

    priority_queue<string, vector<string>, compareWords> pq(compareWords{wordFreq});
                                                                        ^        ^  
    

    并避免priority_queue 的初始化列表构造函数重载,同时不要让构造函数误以为我们正在声明一个函数。感谢 Caleth 指出这个技巧。我忽略了它。

    【讨论】:

    • 为什么不pq(compareWords{wordFreq});
    • 字面意思是因为我没想到。
    猜你喜欢
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    相关资源
    最近更新 更多