本题考点:采用堆栈模拟队列
设已知有两个堆栈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; }
来源:https://www.cnblogs.com/veeupup/p/12628869.html