使用priority_queue需要声明头文件#include
优先队列的使用方法
优先队列包含入队push()(插入元素),出队pop()(删除元素),读取队头元素top(),判断队列是否为空empty()和读取队列元素数量size()等方法;
下例程序具体说明了优先队列的使用方法:
#include
#include
using namespace std;
int main(int argc, char *argv[])
{
//定义优先队列对象,元素类型为整型;
priority_queue
//入队,插入新的元素;
pq.push(1);
pq.push(2);
pq.push(3);
pq.push(9);
//返回队列中元素的个数;
cout << pq.size() << endl;
while(!pq.empty()) { // == pq.empty!=true;
//读取当前队首元素;
cout << pq.top() << " ";
//出队,删除队首元素;
pq.pop();
}
cout << endl;
return 0;
}
运行结果为:
4
9 3 2 1
重载“<”操作符来定义优先级
如果优先队列的元素类型是结构体,可以通过在结构体中重载“<”操作符的方法来修改优先队列的优先性;
下例程序详细说明了在结构体中重载“<”操作符的方法;
运行结果为:
Bomi 18.5
Jack 68.5
Peti 90
#include
#include
#include
using namespace std;
struct Info
{
string name;
float score;
//重载"<"操作符,指定优先级;
bool operator < (const Info &a) const
{
//按score由小到大排列,如果要由大到小排列,使用“>”即可;
return a.score < score;
}
};
int main(int argc, char *argv[])
{
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
//定义优先队列对象,元素类型为Info结构体型;
priority_queue
Info info; //定义结构体变量;
//入队;
info.name = "Jack";
info.score = 68.5;
pq.push(info);
info.name = "Bomi";
info.score = 18.5;
pq.push(info);
info.name = "Peti";
info.score = 90;
pq.push(info);
//元素出队;
while(!pq.empty()) {
//返回队首元素;
cout << pq.top().name << " " << pq.top().score << endl;
//将队头元素弹出;
pq.pop();
}
return 0;
}
重载“()”操作符来定义优先级
如果优先队列的元素不是结构体类型,则可以通过重载“()”操作符的方式来定义优先级,当然,元素是结构体类型,也可以通过重载“()”操作符的方法来定义优先级,而不是一定要在结构体内重载“<”操作符才行;
下例程序说明了重载“()”操作符的方法:
运行结果为:
1 5 9 28 34
#include
#include
using namespace std;
//重载“()”操作符;
struct mycmp
{
bool operator () (const int &a, const int &b)
{
//由小到大排列采用">"号,如果要由大到小排列,则采用"<"号;
return a > b;
}
};
int main(int argc, char *argv[])
{
//定义优先队列,元素类型为Info的结构体,显式说明内部结构是vector;
priority_queue
//入队;
pq.push(1);
pq.push(28);
pq.push(9);
pq.push(5);
pq.push(34);
//元素全部出队;
while(!pq.empty()) {
//返回队首元素;
cout << pq.top() << " ";
//删除队首元素;
pq.pop();
}
cout << endl;
return 0;
}
Windows 消息队列 ZOJ 2724
//ZheJiang University Local Contest 2006
消息队列是Windows操作系统的基石,对于每一个进程,系统维持了一个消息队列,如果一个进程发生了某一事件,如单击鼠标,文本改变,系统将增加一个消息到队列里,同时,如果队列里不是空的,那么,进程将一直循环的从队列里按优先值抓取消息,注意,数值小意味着高的优先级,在本题中,要求你模拟消息队列,把消息放到消息队列中,或从消息队列里抓取消息;
输入描述:
只有一个测试案例,每行是一条命令,“GET”或“PUT”表示从消息队列里抓取消息或把消息放入消息队列。如果是“PUT”命令,后面跟着一个字符串(表示消息名称)和两个整数(分别表示消息的参数和优先级),案例中的命令最多达60000条,注意,一条命令可以重复出现多次,如果两条命令的优先级相同,则先进入消息队列的那条先被处理;一直处理到文件结尾;
输出描述:对于每条“GET”指令,直接输出他抓取的消息的名称和参数在一行上,如果消息队列是空的,那么直接输出“EMPTY QUEUE!”,对于“PUT”指令,不需要输出什么;
Sample Input:
GET
PUT msg1 10 5
PUT msg2 10 4
GET
GET
GET
Sample Output:
EMPTY QUEUE!
msg2 10
msg1 10
EMPTY QUEUE!
解题思路:
本题是模拟Windows处理消息队列,很有意义,解题中主要遇到的问题是超时错误,根据本题的特点,宜使用优先队列容器来实现;
另外,光是用优先队列容器还不行,必须采用scanf和printf输入输出,否则还会超时,因为本题的数据量大,多达60000行字符串需要处理,需要输入输出;
The Code Follows:
#include
#include
#include
#include
using namespace std;
struct Message { //这里不要用typedef了,因为重载运算符参数类型Message不能识别;
char Name[200];
int data, priority;
bool operator < (const Message a) const //重载 < 运算符自定义排序准则;
{
return a.priority < priority;
}
};
int main()
{
priority_queue v; //定义一个优先队列的对象;
char command[200];
while(~scanf("%s", command)) { //输入命令;
Message message;
if(strcmp(command, "GET") == 0) {
if(v.size() == 0) { //队列为空;
printf("EMPTY QUEUE!\n"); //使用cout<<"EMPTY QUEUE"<