题目:
分析:
看到题目,不管题目的ctrl+z
和ctrl+y
操作具体指的是什么,首先要注意到的是这两个操作的对象都是“最近一次之前的操作”,也就是说,我们要对最近的一次操作进行改变,这就和栈的性质很像了,我们只要在栈顶进行操作就能保证是“最近的一次”,所以总体可以先确定的是我们可以用栈来解决。接下来就是要仔细的分析怎么用栈来实现题目的意思。首先,input
操作就是直接往栈s
里面加一个元素,而且元素是字符串,所以可以把栈的类型定为string
(假定我们定义的栈是stack<string>s
)。之后再来看ctrl+z
和ctrl+y
,前者是撤销,后者是恢复。撤销我们可以简单理解为删除元素,而恢复可以简单理解为添加元素。撤销的元素有两种,一是刚刚input
进来的元素,二是刚刚恢复的元素,不管是哪种,这个元素一定是在栈顶,所以可以理解为撤销就是删除栈顶元素。但要注意的是,这个元素可能会被恢复,所以还要用一个栈s1
来暂存被删掉的元素,总结起来,ctrl+z
就是把s
的栈顶元素放进s1
后再删掉。恢复的元素是刚刚被撤销的元素,也就是刚刚被删除的元素,也就是s1
的栈顶元素,也就是说只要把s1
的栈顶元素放回s
再删掉就好了。对于恢复操作还有一点介绍,就是input
之前的撤销不能被恢复,也就是说如果s
新加了一个input
进来的元素,就必须把s1
清空。这样这道题大体上就解决了。最后值得注意的是输出,栈只能输出栈顶元素,并且后进先出,所以如果直接输出的话结果会相反,要稍微处理一下。
代码:
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
int n,i;
string str,str1;
stack<string>s;
stack<string>s1;
cin>>n;
for(i=0;i<n;i++)
{
cin>>str;
if(str=="input")
{
cin>>str1;
s.push(str1);
while(!s1.empty()) //s1要清空
s1.pop();
}
else if(str=="ctrl+z") //撤销操作
{
if(!s.empty())
{
s1.push(s.top());
s.pop();
}
}
else if(str=="ctrl+y") //恢复操作
{
if(!s1.empty())
{
s.push(s1.top());
s1.pop();
}
}
}
if(s.empty())
cout<<"No output"<<endl;
else
{
while(!s1.empty())
s1.pop();
while(!s.empty())
{
s1.push(s.top());
s.pop();
}
while(!s1.empty())
{
cout<<s1.top()<<" ";
s1.pop();
}
}
return 0;
}