使用priority_queue需要声明头文件#include <queue>;
优先队列的使用方法
优先队列包含入队push()(插入元素),出队pop()(删除元素),读取队头元素top(),判断队列是否为空empty()和读取队列元素数量size()等方法;
下例程序具体说明了优先队列的使用方法:
#include <iostream>
#include <queue>
using namespace std;
int main(int argc, char *argv[])
{
//定义优先队列对象,元素类型为整型;
priority_queue <int> pq;
//入队,插入新的元素;
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 <iostream>
#include <queue>
#include <cstdio>
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> pq;
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 <iostream>
#include <queue>
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 <int, vector<int>, mycmp> pq;
//入队;
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:
<span style="font-family:Microsoft YaHei;font-size:18px;">#include <iostream> #include <cstdio> #include <queue> #include <cstring> 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 <Message> 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"<<endl;不会超时; }else { printf("%s %d\n", v.top().Name, v.top().data); //使用cout<<v.top().Name<<v.top().data会超时; v.pop(); //出队列操作,即将当前消息清除; } }else if(strcmp(command, "PUT") == 0) { scanf("%s %d %d", message.Name, &message.data, &message.priority); v.push(message); //入列; } } return 0; } </span>