PTA-7-22 堆栈模拟队列
本题考点:采用堆栈模拟队列
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:
int IsFull(Stack S)
:判断堆栈S
是否已满,返回1或0;int IsEmpty (Stack S )
:判断堆栈S
是否为空,返回1或0;void Push(Stack S, ElementType item )
:将元素item
压入堆栈S
;ElementType Pop(Stack S )
:删除并返回S
的栈顶元素。实现队列的操作,即入队
void AddQ(ElementType item)
和出队ElementType DeleteQ()
。输入格式:
输入首先给出两个正整数
N1
和N2
,表示堆栈S1
和S2
的最大容量。随后给出一系列的队列操作:A item
表示将item
入列(这里假设item
为整型数字);D
表示出队操作;T
表示输入结束。输出格式:
对输入中的每个
D
操作,输出相应出队的数字,或者错误信息ERROR:Empty
。如果入队操作无法执行,也需要输出ERROR:Full
。每个输出占1行。输入样例:
3 2 A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T
输出样例:
ERROR:Full 1 ERROR:Full 2 3 4 7 8 ERROR:Empty
解题思路
采用堆栈模拟队列,堆栈是 FILO,而队列是 FIFO,所以如果我们需要用堆栈模拟队列,至少 需要两个栈。
第一个栈栈用来保存输入的值,而采用第二个栈栈来保存从较小的栈中移动过去的值,此时较大的栈顶部就是最先输入的值了。
而在本题中,所给的两个栈的大小不一样,所以需要选定一个栈当作输入栈,一个栈作为输出栈。
如果我们想尽可能保存多的值,我们需要将较小的栈作为输入栈,较大的栈作为输出栈,这是因为:如果把较大的栈作为输入栈的话,较小的栈无法缓冲从较大的栈中转移过来的值。
在输入过程中,一共会遇到这么几种情况(这里假定较小的栈为 s1
,较大的栈为 s2
):
情况分析
A(输入):
s1
没满,直接放入s1
中s1
满了,s2
为空,先把s1
中的值都暂存到s2
中,再保存到s1
中s1
满了,s2
非空,此时需要输出ERROR:Full
(这是因为如果s1
满了,无论再怎么放入s1
或者s2
都会打乱输出的顺序 )
D(输出):
4. s2
非空,直接输出 s2.top()
5. s1
非空, s2
为空, 那么将 s1
中的值放入 s2
中,然后输出 s2.top()
6. s1
和 s2
都为空,那么输出 ERROR:Empty
代码实现
完整的代码实现如下:
/*
Author: Veeupup
*/
#include <iostream>
#include <cstdio>
#include <cstdint>
#include <stack>
using namespace std;
int s1Size, s2Size;
stack<int> s1; // 容量较小,作为输入栈
stack<int> s2; // 容量较大,作为输出栈
int main()
{
scanf("%d%d", &s1Size, &s2Size);
getchar();
if (s1Size > s2Size)
swap(s1Size, s2Size); // 较小的为输入栈
int s1Num = 0, s2Num = 0, tempNum;
char next;
while (scanf("%c", &next) != EOF)
{
if(next == ' ')
continue;
if (next == 'A')
{
scanf("%d", &tempNum);
if (s1Num < s1Size)
{ // s1 不满,s2 为空,直接放入 s1 中
s1.push(tempNum);
s1Num++;
}
else if (s1Num == s1Size && s2Num == 0)
{ // s1 满,s2 空,将 s1 中都放入 s2 中,再放入 s1 中
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
s2Num++;
s1Num--;
}
s1.push(tempNum);
s1Num++;
}
else if (s1Num == s1Size && s2Num > 0)
{ // s1 满,s2 不为空,输出错误
printf("ERROR:Full\n");
}
}
else if (next == 'D')
{
if (s2Num > 0)
{
printf("%d\n", s2.top());
s2.pop();
s2Num--;
}
else if (s1Num > 0 && s2Num == 0)
{
while (!s1.empty())
{
s2.push(s1.top());
s2Num++;
s1Num--;
s1.pop();
}
printf("%d\n", s2.top());
s2Num--;
s2.pop();
}
else if (s1Num == 0 && s2Num == 0)
{
printf("ERROR:Empty\n");
}
}
}
return 0;
}