C++使用对象的优先级队列

C++ using a priority queue of objects

本文关键字:优先级 队列 对象 C++      更新时间:2023-10-16

我想做一个对象的优先级队列,特别是一对(int,int)。队列应包含分配有优先级的对。

#include <iostream>
#include <queue>
using namespace std;    
class saPair{
public:
int s;
int a;
double priority;
saPair(int s, int a, double priority){
this->s = s;
this->a = a;
this->priority = priority;
}
};
// the priority menmber variable determines the priority in the queue
// highest priority pair of (int, int) stays on the top
bool operator< (const saPair& x, const saPair& y) {
return x.priority < y.priority;
}

int main()
{
priority_queue<saPair> pq;
pq.push(saPair(0,0, 0.3));
pq.push(saPair(0,1, 0.1));
pq.push(saPair(0,3, 0.5));
pq.push(saPair(0,3, 5));
cout << pq.top().a << endl;
pq.pop();
cout << pq.top().a << endl;
pq.pop();
cout << pq.top().a << endl;

}

如您所见,该对 (0,3) 具有最高优先级,因此它保持在顶部。但是我的实现的问题在于,如果我再次添加具有不同优先级的 (0,3) 对,我会向队列添加一个新元素,而不是替换已经存在的 (0,3) 对的优先级。

我觉得我为我的要求选择了错误的数据结构。我尝试通过定义一个新的saPair(int,int)类来获取键值<运算符的操作重载。但即使这样似乎也无法正常工作。>

关于如何继续的任何建议? 或修改

似乎您需要对容器进行多键访问:您希望按优先级对其进行排序(或者至少像priority_queue一样按优先级进行二进制堆),并且您希望对值是唯一的,因此您还需要对值查找。

在标准库中没有默认的解决方案,但制作自己的解决方案应该不会太难。

我建议简单地存储一个额外的std::set<saPair>来检查这对是否已在您的容器中。通过这种方式,您可以保持priority_queue原样,并且不会花费太多精力来实施。

不要忘记将operator<添加到saPair(或将其替换为std::pair),否则std::set将无法使用它。

另一种选择是每次添加时手动检查priority_queue是否有一对。虽然渐近比std::set解决方案更糟糕,但这在实践中可能会更快,并且会为您节省一些空间。但是我认为如果您使用std::set,代码会更干净。

另一种解决方案是boost::multi_index,它允许您轻松构建所需的任何多索引容器。但是,我认为它不会让您利用您不需要按优先级进行强排序的事实,因此它不会像priority_queue那样具有线性连续布局。