stl整理——队列,优先队列

队列,优先队列

queue俗称队列,是STL中常用的容器之一,使用时需要引用头文件#include<queue>他与栈十分相似,可以说是一个两端开口的栈,每次都可以向队尾插入元素,从队头删除一个元素。
1.定义queue:

queue<int>q1;
queue<double>q2;  
queue<char>q3;

2.常用函数:

push() 在队尾插入一个元素
pop() 删除队列第一个元素
size() 返回队列中元素个数
empty() 如果队列空则返回true
front() 返回队列中的第一个元素
back() 返回队列中最后一个元素

来一道简单的队列模板题

Throwing cards away I

给出的是一副有序的n张牌,编号为1至n,牌1在上,牌n在下。只要这副牌中至少有两张牌,就可以进行以下操作。

扔掉最上面的一张牌 然后把现在在最上面的那张牌移到最下面去.

你的任务是找到被丢弃的牌和最后一张剩余的牌的顺序。

每一行输入(除了最后一行)都包含一个数字n≤50。最后一行包含0,这一行不应该被处理。对于输入的每个数字产生两行输出。第一行显示被丢弃的牌的序列,第二行报告最后剩下的牌。任何一行都不会有前导或尾部的空格。参见示例中的预期格式。

Sample input
7
19
10
6
0

Output
Discarded cards: 1, 3, 5, 7, 4, 2
Remaining card: 6
Discarded cards: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 4, 8, 12, 16, 2, 10, 18, 14
Remaining card: 6
Discarded cards: 1, 3, 5, 7, 9, 2, 6, 10, 8
Remaining card: 4
Discarded cards: 1, 3, 5, 2, 6
Remaining card: 4

题目要求很简单给出1-n张牌利用queue进行模拟输出即可(这里我是手写了一个数组q来模拟队列)

#include<iostream>
#include<cstring>
using namespace std;
int n;

int main() {
	while (~scanf("%d", &n)) {
		int q[1000];
		int a[1000];
		if (n == 0)break;
		for (int i = 1; i <= n; i++)q[i] = i;
		int hh = 1, tt = n; int m = 1;
		while (hh < tt) {
			a[m++] = q[hh];
			hh++;
			q[++tt] = q[hh++];
		}
		if(n!=1)
		printf("Discarded cards: ");
		else {
			printf("Discarded cards:\n");
			printf("Remaining card: 1\n");
			continue;
		}
		for (int i = 1; i < m; i++)
		{
			if (i != m - 1)
				printf("%d, ", a[i]);
			else
				printf("%d\n", a[i]);
		}
		printf("Remaining card: %d\n", q[hh]);
	}
}

再来看一下他的孪生同胞priority_queue同样也是要使用#include<queue>,虽然名字看起来都有队列俩字,但是优先队列和队列的结构大不相同,优先队列是一个堆,默认为大根堆(树根为最大的数),是一个树状结构。

模板申明带3个参数:priority_queue<Type, Container, Functional>,其中Type 为数据类型,Container为保存数据的容器,Functional 为元素比较方式。

Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的vector。
1.定义

 priority_queue<int> q;/一般定义
 priority_queue<struct a> q;/与结构体结合的定义
 priority_queue<pair<int,int> > coll;/结合pair内部按pair的first元素降序,first相同再按second元素降序。
 priority_queue<int, vector<int>, greater<int> > q;/小根堆的定义方式需要引用第三个参数
 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > coll;
 /先按照pair的first元素升序,first元素相等时,再按照second元素升序
 

来道题来看看运用时出现的问题吧
在这里插入图片描述
先来翻译一下巨长的题干0.0
题目描述
一个数据流是一个实时,连续,有序的条目序列。一些实例包括传感器数据,互联网贸易,金融报价,网上拍卖,交易日志,Web使用日志和电话呼叫记录。同样,在数据流上的查询每隔一定时间就要连续运行,在产生新的数据的时候就要产生新的结果。例如,一家工厂的仓库的温度检测系统可以执行如下的查询:
查询- 1:“每五分钟,检索在过去5分钟内的最高温度。”
查询- 2:“返回在过去10分钟各个楼层的平均气温。”
我们开发了一个名为Argus的数据流管理系统,以处理在数据流上的查询。用户可以在Argus上登记查询。 Argus将在不断变化的数据上持续执行查询,并以要求的频率向相应的用户返回结果。
对Argus,我们以下述的指令来登记查询:
Register Q_num Period
Q_num (0 < Q_num <= 3000)是查询的ID编号,Period (0 < Period <= 3000)是两个连续的查询结果返回之间的时间间隔。在登记了Period秒之后,首次返回结果,此后,每隔Period秒返回结果。
在Argus上登记了几个不同的查询,所有的查询都有不同的Q_num。你的任务是给出前K个返回结果的查询。如果两个或多个查询同时返回结果,则将他们按照Q_num的升序进行排列。

输入
输入的第一部分是在Argus上登记的指令,一条指令占一行,假定指令的编号不超过1000,并且所有的指令同时开始执行。这一部分的结束用“#”表示。
第二部分是你的工作,只有一行,给出一个正整数K (<= 10000)。

输出
输出前K个返回结果的查询的Q_num,每个数字一行。
样例输入

Register 2004 200
Register 2005 300

5

样例输出

2004
2005
2004
2004
2005
思路很简单啊,给一个标号一个时间,每过这个时间一次输出标号,优先输出较小的标号。
但是在写代码的时候我用到了结构体,碰到了很多麻烦。(小蒻蒟第一次)

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct re {
	int num, sec;
	bool operator<(const re& c) const //重载运算符
	{
		return sec > c.sec || (sec == c.sec && num > c.num); //时间从小到大排序,相同的标号小的优先
	}
};

priority_queue<struct re>s;

int main() {
	while (1) {
		string op;
		op.clear();

		cin >> op;
		if (op == "#")break;
		else {
			int a, b;
			re n;
			scanf("%d %d", &a, &b);
			for (int i = 1; i <= 3100; i++) {
				n.num = a;
				n.sec = b*i;
				s.push(n);
			}
		}
	}
	int k;
	scanf("%d", &k);
	for (int j = 1; j <= k; j++) {

		cout << s.top().num << endl;
		s.pop();
	
	
	}
	return 0;
}

在网上搜索之后,发现如果使用自定义类型时,需要重载operator<或者重写仿函数。

bool operator<(Node a, Node b){/返回true时,说明a的优先级低于b
    /x值较大的Node优先级低(x小的Node排在队前)
    /x相等时,y大的优先级低(y小的Node排在队前)
     if( a.x== b.x ) return a.y> b.y;
     return a.x> b.x; 
 }
 可以写在结构里内部,也可以写在外面。

也可以像结构体排序一样

struct cmp{
    bool operator() ( Node a, Node b ){//默认是less函数
        //返回true时,a的优先级低于b的优先级(a排在b的后面)
        if( a.x== b.x ) return a.y> b.y;      
      return a.x> b.x; }
};
priority_queue<a, vector<struct a>, cmp> q;

队列的内容大致就到这了,小编还会继续学习和更新。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值