【问题标题】:Can the stl c++ priority queue be used with stl set?stl c++优先级队列可以和stl set一起使用吗?
【发布时间】:2012-09-11 18:04:33
【问题描述】:

我的问题与Is there a Queue (PriorityQueue) implementation which is also a Set? 相同,只是这个问题是关于 c++ 和 stl 的。

是否可以使用将stl设置为容器类的stl优先级队列?如果没有,是否有一个替代容器类可以与优先级队列一起使用以使其成为一个集合?

【问题讨论】:

  • 不要问如何将方钉塞入圆孔中,您能说出您想要完成的任务吗? (除了折断钉子的角<g>
  • 为什么要把它做成一套?您想要独特的会员资格吗?
  • @KerrekSB 是的,我想要唯一的会员资格。
  • 更具建设性:容器适配器queue 需要一个容器类型,允许在其后面推送新元素并从前面弹出元素。 std::set 不这样;它有自己的元素应该处于的顺序的概念,因此不支持推送和弹出。
  • std::priority_queue 的序列要求不仅仅是推送和弹出。 owagh 你应该自己阅读容器要求。你可以这样做,但它需要你滚动一个容器来建立你放置的额外约束(唯一性),因为我不知道有一个股票标准容器可以满足所有要求 + 唯一性(我假设你会通过在违规时抛出异常来强制执行)。

标签: c++ stl set priority-queue


【解决方案1】:

std::priority_queue 的规范不允许“唯一成员资格”。如果您希望优先级队列中的唯一成员资格,那么您不需要std::priority_queue

如果您想要一个具有唯一成员资格的优先级队列实现,那么 std::set已经这样做了,因为它保持其成员排序。

【讨论】:

  • 我没有意识到由于 set 已经排序,它已经 一个优先级队列。谢谢。
【解决方案2】:

这可能不是最有效的实现方式,但您可以这样做。 (注意,我不是在这里尝试满足 std::priority_queue 的确切接口,对更改比较运算符、底层容器或 std::set 分配器不感兴趣)。

而不是在推送重复项时抛出,此实现只是假装推送成功。

template<class T>
class UniquePriorityQueue
{
public:
    typedef typename std::priority_queue<T>::size_type size_type;

    void push(const T& v)
    {
        auto i = membership_.insert(v);
        if(i.second)
        {
            queue_.push(v);
        }
    }

    void pop(void)
    {
        membership_.erase(queue_.top());
        queue_.pop();
    }

    const T& top() const
    {
        return queue_.top();
    }

    bool empty() const
    {
        return queue_.empty();
    }

    size_type size() const 
    {
        return queue_.size();
    }

private:
    std::priority_queue<T> queue_;
    std::set<T> membership_;
};

驱动实现的功能的主...

int main()
{
    UniquePriorityQueue<int> q;
    q.push(1);
    q.push(1);
    q.push(8);
    q.push(4);
    q.push(2);
    q.push(8);
    q.push(5);
    q.push(7);

    assert(q.size() == 6);
    assert(q.top() == 8);
    q.pop();

    assert(q.top() == 7);
    q.pop();

    assert(q.top() == 5);
    q.pop();

    assert(q.top() == 4);
    q.pop();

    assert(q.top() == 2);
    q.pop();

    assert(q.top() == 1);
    q.pop();

    assert(q.empty());  
}

【讨论】:

    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2013-03-16
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    相关资源
    最近更新 更多