优先队列比较

Posted

技术标签:

【中文标题】优先队列比较【英文标题】:Priority Queue Comparison 【发布时间】:2013-12-29 14:22:03 【问题描述】:

我正在尝试使用自定义比较函数在 C++ 中声明优先级队列...

所以,我将队列声明如下:

std::priority_queue<int,std::vector<int>, compare> pq;

这里是比较函数:

bool compare(int a, int b)

   return (a<b);

我很确定我以前这样做过,没有类,以类似的方式,但现在,这段代码无法编译,我收到了几个这样的错误:

type/value mismatch at argument 3 in template parameter list for 'template<class _Tp, class _Sequence, class _Compare> class std::priority_queue'

有没有办法在不使用类的情况下创建与此类似的比较函数?

谢谢

【问题讨论】:

试试&amp;compare。如果这不起作用,您也可以使用std::less&lt;int&gt;。模板参数可能是函子的类型,而不是函子/函数值。 谢谢,但不, &compare 不起作用....我问这个的原因是因为我想对结构进行排序,基于它们的价值之一,所以 std::less 不会真的不行…… 【参考方案1】:

模板参数应该是比较函数的类型。然后该函数是默认构造的,或者您在priority_queue 的构造函数中传递一个函数。所以尝试一下

std::priority_queue<int, std::vector<int>, decltype(&compare)> pq(&compare);

或者不使用函数指针,而是使用标准库中的仿函数,然后可以默认构造,从而无需在构造函数中传递实例:

std::priority_queue<int, std::vector<int>, std::less<int> > pq;

http://ideone.com/KDOkJf

如果您的比较函数无法使用标准库函子表达(如果您在优先级队列中使用自定义类),我建议编写一个自定义函子类,or use a lambda。

【讨论】:

嗯...这很奇怪,但第一个不适合我。我从 Ideone 复制了代码,但它不起作用... 其实我不确定...我正在使用代码块 12.11 和与之一起安装的编译器... 但它有个缺点,如果你改变compare的签名,你也必须相应地改变CompareType。其他代码使用decltype,它将为您提供() 中的内容类型,但它仅在C++11 之后可用。 是的......这行得通,但与 Emil Condrea 的回答一样,我不明白为什么...... 啊,好的,明白了.. 你需要传递一个类型,就像另一个人对 pqueue 说的那样......谢谢【参考方案2】:

您可以使用 C++11 lambda 函数。您需要创建 lambda 对象,使用 decltype 将其传递给模板,并将其传递给构造函数。它看起来像这样:

auto comp = [] (int &a, int &b) -> bool  return a < b; ;
std::priority_queue<int,std::vector<int>, decltype(comp) > pq (comp);

【讨论】:

模板中第二个参数“std::vector”的作用是什么? @MohammadMamunHossain:这是底层容器的默认值。【参考方案3】:

你必须在priority_queue构造函数中指定函数类型并实例化函数。

#include <functional>

bool compare(int a, int b)

   return (a<b);


std::priority_queue<int, std::vector<int>,
                              std::function<bool(int, int)>> pq(compare);

【讨论】:

【参考方案4】:

这对我来说非常有效。

struct compare
    bool operator() (const int& p1,const int& p2 )
         return p1<p2;
    
;

int main()
    priority_queue<int,vector<int>, compare > qu;
return 0;

【讨论】:

这看起来是众多解决方案中最简单的。【参考方案5】:

您可以使用 typedef。这编译得很好:

typedef bool (*comp)(int,int);
bool compare(int a, int b)

   return (a<b);

int main()

    std::priority_queue<int,std::vector<int>, comp> pq(compare);
    return 0;

【讨论】:

但是它不起作用,因为你没有传递一个函数,只有一个类型告诉它的签名。 啊,谢谢,这编译得很完美,但我仍然不明白它是如何工作的,以及我可以添加我的自定义比较的方式......如果你能澄清一点就好了!谢谢! 你说得对,我忘了把函数添加为构造函数的参数 我更新了我的答案,这次没有忘记将比较函数传递给构造函数。【参考方案6】:
std::priority_queue<int, std::vector<int>, bool (*)compare(int, int)> pq(compare);

另一种方式没有提到。

【讨论】:

以上是关于优先队列比较的主要内容,如果未能解决你的问题,请参考以下文章

优先队列比较

优先队列原理与实现

优先队列的自定义比较功能

Java集合与数据结构——优先级队列的使用及练习

具有自定义比较器的最小优先级队列

优先级队列(JavaScript实现)