堆栈模拟队列
题目大意
PTA上的一道题,详题见文末。
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
输入:
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
思路
最开始设想的是将长度小的栈作为存储栈,长度大的栈作为过渡输出栈,虽然可以实现队列,但是这种操作的时间复杂度和空间浪费都比较大,而且不合题意。
这道题目其实已经将思路藏在输出样例中了,要按照输入与输出对的样例来纠正,当输入A 5
时,队列才满,所以其实可以理解为将S2作为了队头,而S1作为输入的队尾。当S2空时,根据是否刚好需要输出 或者 刚好S1长度符合S2时,将S1移入S2,完成队头的生成。
这样的队列长度最长可到2*N2,空间利用率会更高,速度也会较快。
代码实现
#include<bits/stdc++.h>
using namespace std;
stack <int> s1,s2;
int N1,N2;
void move(void){
while(!s1.empty()){int tem;tem=s1.top();s1.pop();s2.push(tem);}
}
void AddQ(int item){
if(!s2.empty() && s1.size()==N2)cout<<"ERROR:Full"<<endl;
else if(s2.empty() && s1.size()==N2){move();s1.push(item);}
else s1.push(item);
}
int DeleteQ(){
if(s1.empty()&&s2.empty())cout<<"ERROR:Empty"<<endl;
else if(!s2.empty()){cout<<s2.top()<<endl;s2.pop();}
else{move();cout<<s2.top()<<endl;s2.pop();}
}
int main(){
cin>>N1>>N2;
int item;
char c;
cin>>c;
while(c!='T'){
if(c=='A'){
cin>>item;
AddQ(item);
}
else DeleteQ();
cin>>c;
}
return 0;
}