【问题标题】:Priority Queues in c++C++ 中的优先级队列
【发布时间】:2017-06-13 17:58:35
【问题描述】:

有没有办法在 c++ 中迭代优先级队列?我的理解是它们或多或少是不可变的,容器的唯一操作是顶部元素。我希望能够打印出优先队列的内容,但我不确定如何解决这个问题。

【问题讨论】:

  • 我想一种快速而肮脏的方法是复制和出列。
  • 不确定 C++ 中是否有任何新内容改变了 advice in this question
  • 你问的是 std::priority_queue 吗?
  • @Neil Butterworth 是的
  • @Keith 那么不,不是没有复制或修改队列。我一直认为队列和堆栈应该提供对底层容器的读取访问权限,但事实并非如此。

标签: c++ iterator priority-queue


【解决方案1】:

底层容器是一个名为cprotected 数据成员(有关详细信息,请参阅here)。因此,您始终可以从 std::priority_queue 继承并导出该容器上的几个迭代器(如果可用)。
作为一个最小的工作示例:

#include<queue>
#include<iostream>

struct MyPriorityQueue: std::priority_queue<int> {
    auto begin() const { return c.begin(); }
    auto end() const { return c.end(); }
};

int main() {
    MyPriorityQueue pq;
    pq.push(0);
    pq.push(1);
    for(auto &v: pq) {
        std::cout << v << std::endl;
    }
}

注意:通常不鼓励从 std:: 命名空间中的数据结构继承。
话虽如此,它至少有效。


上面的代码在 C++14 中工作。
下面是根据 cmets 的要求在 C++11 中也可以使用的稍作修改的版本:

#include<queue>
#include<iostream>

struct MyPriorityQueue: std::priority_queue<int> {
    decltype(c.begin()) begin() const { return c.begin(); }
    decltype(c.end()) end() const { return c.end(); }
};

int main() {
    MyPriorityQueue pq;
    pq.push(0);
    pq.push(1);
    for(auto &v: pq) {
        std::cout << v << std::endl;
    }
}

【讨论】:

  • auto begin() 给出错误 C3551:预期尾随返回类型。至少在使用 VS2013 编译时。
  • @Laszlo 这是 C++14。放在那里正确的类型或decltype 让它在 C++11 中工作。无论如何,我正在更新答案。
  • error: could not convert ‘((const MyPriorityQueue*)this)-&gt;MyPriorityQueue::&lt;anonymous&gt;.std::priority_queue&lt;int&gt;::c.std::vector&lt;_Tp, _Alloc&gt;::begin&lt;int, std::allocator&lt;int&gt; &gt;()’ from ‘std::vector&lt;int, std::allocator&lt;int&gt; &gt;::const_iterator {aka __gnu_cxx::__normal_iterator&lt;const int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;}’ to ‘std::vector&lt;int, std::allocator&lt;int&gt; &gt;::iterator {aka __gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;}’ decltype(c.begin()) begin() const { return c.begin(); }
【解决方案2】:

根据@skypjack 的回答,这是一个模板版本:

#include<queue>
#include<iostream>

template<class T, class C = vector<T>, class P = less<typename C::value_type> >
struct MyPriorityQueue :
   std::priority_queue<T,C,P> {
   typename C::iterator begin() { return std::priority_queue<T, C, P>::c.begin(); }
   typename C::iterator end() { return std::priority_queue<T, C, P>::c.end(); }
};

int main() {
   MyPriorityQueue<int> pq;
   pq.push(0);
   pq.push(1);
   for (auto &v : pq) {
      std::cout << v << std::endl;
   }
}

【讨论】:

  • 无法与typedef 一起使用,例如:typedef MyPriorityQueue&lt;Obj, vector&lt;Obj&gt;, Cmp&gt; customq_type; customq_type customq(param); 获取以下内容:error: no matching constructor for initialization of customq_type。请帮忙。
  • 这是因为构造函数没有被继承。 using priority_queue&lt;T,C,P&gt;::priority_queue,我们应该可以继承构造函数。
猜你喜欢
  • 2011-12-20
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2019-04-25
相关资源
最近更新 更多