【问题标题】:Ordering issue while popping from priority_queue, Is this a bug with std::priority_queue从 priority_queue 弹出时的排序问题,这是 std::priority_queue 的错误吗
【发布时间】:2018-01-01 23:24:10
【问题描述】:
#include <functional>
#include <queue>
#include <vector>
#include <iostream>

 struct Temp
 {
   int p;
   std::string str;
 };

 struct TempCompare
 {
     bool operator()(Temp const & a, Temp const & b)
     {
         return a.p > b.p;
     }
 };

int main() {

    std::priority_queue<Temp, std::vector<Temp>, TempCompare> pq;
    //Enable and Disable the following line to see the different output
    //{Temp t; t.p=8;t.str="str1";pq.push(t);} 
    {Temp t; t.p=8;t.str="str2";pq.push(t);}
    {Temp t; t.p=9; t.str="str1";pq.push(t);}
    {Temp t; t.p=9; t.str="str2";pq.push(t);}

    while(!pq.empty())
    {
        std::cout << pq.top().p << " " << pq.top().str << std::endl;
        pq.pop();
    }
}

运行上述程序,启用和禁用 main 中的第四行;禁用时得到的输出是

8 str2
9 str1
9 str2

而当它启用时,你会得到

8 str1
8 str2
9 str2
9 str1

行为是否应该保持一致?

【问题讨论】:

  • 是否有文档表明对于相等元素的排序是“稳定的”?如果不是,则该行为似乎是可能的,但不一定是您所期望的。
  • 有稳定的排序算法,比如std::stable_sort,但是heapsort is not one of them

标签: c++ c++11 stl std priority-queue


【解决方案1】:

没有。没有理由让行为保持一致。根据您的比较函数,Temp{9, "str1"}Temp{9,"str2"} 相等,因此它们以任意顺序返回。向队列中添加不同的元素很可能会改变该顺序。

如果您希望它们以一致的顺序返回,则需要扩展比较功能。最简单的方法是

     bool operator()(Temp const & a, Temp const & b)
     {
         return std::tie(a.p,a.str) > std::tie(b.p,b.str);
     }

如果你想要“在p 中下降,但在str 中上升”,你必须自己做。

【讨论】:

  • 我希望我能给你一个以上的“赞成”票来支持使用std::tie
  • "p 降序,str 升序" -> return std::tie(b.p,a.str) &lt; std::tie(a.p,b.str)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-16
  • 1970-01-01
  • 2018-09-18
相关资源
最近更新 更多