【问题标题】:Why does priority_queue in STL not follow strict weak ordering?为什么 STL 中的 priority_queue 不遵循严格的弱排序?
【发布时间】:2017-01-07 16:20:08
【问题描述】:

我一直在玩 STL 容器和它们支持的比较函数/仿函数,但是我发现 priority_queue 不遵循通常的严格弱排序,我试图了解可能是什么原因但无法弄清楚出来,任何指针都会有所帮助。

在这篇博客中还提到priority_queue不遵循严格的弱排序。 enter link description here

#include "STL.h"
#include "queue"
#include "vector"
#include "iostream"
#include "functional"
using namespace std;

typedef bool(*func)(const int& val1 , const int& val2);

bool strict_weak_order_function(const int& val1 , const int& val2){
    return val1 > val2;
}

bool comparer_function(const int& val1 , const int& val2){
    return !strict_weak_order_function(val1 , val2);
}

struct Compaper_functor{
    bool operator()(const int& val1 , const int& val2){
        return !strict_weak_order_function(val1 , val2);
    }
};


void runPriorityQueue(void){
    //priority_queue<int , vector<int> , func > pq(comparer_function);
    priority_queue<int , vector<int> , Compaper_functor > pq;
    int size;
    cin >> size;
    while(size--){
        int val;
        cin >> val;
        pq.push(val);
    }
    while(!pq.empty()){
        cout <<'\n'<< pq.top() << '\n';
        pq.pop();
    }
}

【问题讨论】:

  • " 我发现 priority_queue 不遵循通常的严格弱排序" 需要引用。
  • 你的意思是顺序颠倒了吗?即 less 的谓词在 priority_queue 的后面插入较低的项目?
  • @arup priority_queue 确实需要严格的弱排序。你需要重新评估你的假设!
  • ideone.com/8kR9qQ ,根据函子 5
  • 可能是RTFM

标签: c++ stl priority-queue strict-weak-ordering


【解决方案1】:

问题是你的strict_weak_order(使用&gt;)的否定是&lt;=,这不是一个严格的弱命令。对于所有x,严格的弱顺序R 必须满足x R x == false。但是,R 等于 &lt;= 会产生 (x &lt;= x) == true

您需要颠倒参数的顺序(对应于&lt;)。

bool comparer_function(const int& val1 , const int& val2){
    return strict_weak_order_function(val2 , val1);
}

struct Compaper_functor{
    bool operator()(const int& val1 , const int& val2){
        return strict_weak_order_function(val2 , val1);
    }
};

但是请注意std::priority_queue 有一个std::less 作为默认比较器,但that gives a max-heap(即[5, 4, 3, 2, 1] 来自同一输入的输出),所以要获得一个最小堆(即输出[1, 2, 3, 4, 5] 从输入[5, 4, 3, 2, 1]) 你需要通过std::greater,见eg这个:

#include <queue>
#include <iostream>

int main()
{
    auto const v  = std::vector<int> { 5, 4, 3, 2, 1 };

    // prints 5 through 1
    for (auto p = std::priority_queue<int> { v.begin(), v.end()  }; !p.empty(); p.pop())
        std::cout << p.top() << ',';
    std::cout << '\n';

    // prints 1 through 5
    for (auto p = std::priority_queue<int, std::vector<int>, std::greater<int>> { v.begin(), v.end()  }; !p.empty(); p.pop())
        std::cout << p.top() << ',';
    std::cout << '\n';
}

Live Example

【讨论】:

猜你喜欢
  • 2010-11-20
  • 2013-05-25
  • 2017-05-28
  • 2016-02-04
  • 2013-02-14
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多