如何在不遍历的情况下获取优先级队列的最后一个元素
How to get last element of priority queue without traversing it
我有以下优先级队列:
#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
struct Time {
int h; // >= 0
int m; // 0-59
int s; // 0-59
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
};
int main()
{
priority_queue<Time, vector<Time>, CompareTime> pq;
// Array of 4 time objects:
Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};
for (int i = 0; i < 4; ++i)
pq.push(t[i]);
while (! pq.empty()) {
Time t2 = pq.top();
cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
setw(3) << t2.s << endl;
pq.pop();
}
return 0;
}
现在为了得到最后一个元素,我必须 pop() 队列中的所有元素。有什么方法可以让我只检索此优先级队列的最后一个元素。
我知道可以颠倒 "CompareTime" 中的顺序,使最后一个元素成为第一个元素。我不想这样做,因为我想按照 "CompareTime" 确定的顺序从优先级队列中弹出()元素。但与此同时,我还想要优先级队列的最后一个元素……而不是从优先级队列中弹出所有元素。是否可以确定优先级队列最后一个元素的值。
我正在使用以下 gcc 编译器:gcc (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
std::priority_queue 不支持你想直接做的事情。请参阅:
http://www.cplusplus.com/reference/queue/priority_queue/
当然,您始终可以创建自己的 DS,但有一些库容器可以满足您的需要。
编辑:
您可以考虑使用
std::set
http://en.cppreference.com/w/cpp/container/set
它是有序的,可以快速访问第一个和最后一个元素,也可以快速删除任何元素。请注意,元素必须是唯一的。如果你不想,你可以使用
std::multiset
哪个更灵活,可以解决问题。
用于获取两端的元素
std::set::begin
std::set::rbegin
迭代器可用。由于集合始终排序,因此这些是最小和最大元素。
希望对您有所帮助!
您可以将值存储为一些大值 - 实际值
然后在检索时执行相同的操作,即大值 - 队列(顶部)值。
例如
比如,大值 = 100
然后存储
56 等于 44
20 等于 80 ...
并在检索时
80 等于 100-80 = 20
这就是您如何以相反的优先顺序填充队列;)
我有以下优先级队列:
#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
struct Time {
int h; // >= 0
int m; // 0-59
int s; // 0-59
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
};
int main()
{
priority_queue<Time, vector<Time>, CompareTime> pq;
// Array of 4 time objects:
Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};
for (int i = 0; i < 4; ++i)
pq.push(t[i]);
while (! pq.empty()) {
Time t2 = pq.top();
cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
setw(3) << t2.s << endl;
pq.pop();
}
return 0;
}
现在为了得到最后一个元素,我必须 pop() 队列中的所有元素。有什么方法可以让我只检索此优先级队列的最后一个元素。
我知道可以颠倒 "CompareTime" 中的顺序,使最后一个元素成为第一个元素。我不想这样做,因为我想按照 "CompareTime" 确定的顺序从优先级队列中弹出()元素。但与此同时,我还想要优先级队列的最后一个元素……而不是从优先级队列中弹出所有元素。是否可以确定优先级队列最后一个元素的值。
我正在使用以下 gcc 编译器:gcc (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
std::priority_queue 不支持你想直接做的事情。请参阅: http://www.cplusplus.com/reference/queue/priority_queue/
当然,您始终可以创建自己的 DS,但有一些库容器可以满足您的需要。
编辑:
您可以考虑使用
std::set
http://en.cppreference.com/w/cpp/container/set
它是有序的,可以快速访问第一个和最后一个元素,也可以快速删除任何元素。请注意,元素必须是唯一的。如果你不想,你可以使用
std::multiset
哪个更灵活,可以解决问题。
用于获取两端的元素
std::set::begin
std::set::rbegin
迭代器可用。由于集合始终排序,因此这些是最小和最大元素。
希望对您有所帮助!
您可以将值存储为一些大值 - 实际值 然后在检索时执行相同的操作,即大值 - 队列(顶部)值。 例如 比如,大值 = 100 然后存储 56 等于 44 20 等于 80 ... 并在检索时 80 等于 100-80 = 20
这就是您如何以相反的优先顺序填充队列;)