【问题标题】:How to use different comparators for the same priority queue?如何为相同的优先级队列使用不同的比较器?
【发布时间】:2018-03-02 04:22:52
【问题描述】:

根据条件,我需要在同一个vector<Objects>上使用不同的比较器类

priority_queue<Object, vector<Object>> pq;

if (something...)
    priority_queue<Object, vector<Object>, Comp1> pq;
else if(...)
    priority_queue<Object, vector<Object>, Comp2> pq;
else
    priority_queue<Object, vector<Object>, Comp3> pq;

... All further code works on pq & does not change on the conditions.

我如何实现这一目标?我发现不建议更改比较器,因为它会导致未定义的行为,但在这里我只需要根据某些条件初始化不同的比较。

【问题讨论】:

  • 这个问题非常模糊,但是如果您需要“基于某些条件”更改比较,为什么不将这些条件包含在您的比较函数中?
  • 这似乎是个好主意! :D
  • 那会有问题。您可能需要重新审视自己的需求并找到不同的解决方案。

标签: c++ comparator priority-queue


【解决方案1】:

使用std::function&lt;bool(Object const&amp;, Object const&amp;)&gt; 作为比较器,然后在构造过程中传入适当的函子。

//typedef just void repeating myself over and over
typedef priority_queue<Object, vector<Object>, std::function<bool(Object const&, Object const&)>> queue_type;
queue_type pq;
if (something...)
    pq = queue_type{std::less<Object>{}};
else if(...)
    pq = queue_type{std::greater<Object>{}};
else
    pq = queue_type{...};

注意,在队列的构造过程中如果没有提供有效的比较函数,在进行任何依赖于比较的操作时都会引发异常。

【讨论】:

  • 虽然它提供了一个语法正确的解决方案,但它在语义上并不正确。将std::less 用于priority_queue 的一部分,将std::greater 用于priority_queue 的另一部分很可能会导致奇怪的行为。
  • 这不是一部分。您正在创建一个新的优先级队列,并替换原来的优先级队列(删除所有内容)。如果要对队列重新排序,则不能使用 std::priority_queue。如果您说要创建一个队列,该队列具有基于升序或降序的排序顺序,然后将其填充并完全使用它,则此方法有效。如果不替换队列的所有内容,就无法更新比较运算符
  • 我明白了。我希望这就是 OP 所需要的。
  • 你将如何使用 Comparator 类而不是函数来做呢?
  • 另外,我在使用这个代码错误的 sn-p 时遇到这个错误(即 arg.3 无效):` 模板参数 3 无效 typedef std::priority_queue, std::function&lt;bool(int const&amp;, int const&amp;)&gt; queue_type; 我在这里使用int 而不是Object 只是为了证明概念。
【解决方案2】:

您也可以将代码重写为:

template <typename Comp>
void foo()
{
    priority_queue<Object, vector<Object>, Comp> pq;
    // ... All further code works on pq & does not change on the conditions.
}

然后

if (something...) {
    foo<Comp1>>();
} else if(...) {
    foo<Comp2>>();
} else {
    foo<Comp3>>();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多