2. 实现字符串的撤销(undo)与恢复撤销(redo)
-
**题目描述:**undo就是撤销undo的前一个所输入的字符串,redo就是恢复之前撤销的字符串
输入示例:
hello undo redo world.
输出示例:
hello world.
-
分析:
对输入的字符串,分三种情况:
(1)输入为正常字符串,直接放到结果数组r;
(2)若碰到undo,且结果数组r不为空,则将结果数组r的最后一个字符串删除并暂存到一个栈里边;
(3)若碰到redo,且redo之前有执行undo(即删除栈里有值),则将之前删除的字符串恢复【所以这个恢复的位置有点迷,不知道是恢复到原位置还是恢复到当前位置,还是要把当前字符串进行覆盖】。据牛客已AC的人说要覆盖当前的字符串,也就是当输入为hello undo world redo
的时候,要恢复hello,则用hello去覆盖redo之前的字符串world,所以这个例子的输出为hello
。
最后输出结果数组即可。
现在有一个问题,对于输入的多个字符串数据该怎么结束输入,我用的while(cin>>str)
到最后没有办法结束输入,只能Ctrl+C。
找了一个例子:c++读一行数字以换行结束,读一行句子以换行结束,读多行字符串
所以只需要在while(cin>>str){}
内部再定义一个char
字符专门用来捕获输入字符串最后的换行字符'\n'
即可(注意是字符类型char
),若捕获到了换行字符,就break
跳出整个while
,我这里需要对每一次输入的字符串进行操作,所以这个if判断放到了while循环的最后执行,不然就会少处理一个字符串。具体代码如下:
//输入字符串,直到遇到回车'\n'结束
while(cin>>str)
{
char ch = getchar();
//对str的一些操作
if(ch == '\n')
break;
}
- 代码:
/*
undo表示撤销前一个字符操作,redo表示恢复刚才撤销的字符串
*/
#include<iostream>
#include<string>
#include<stack>
#include<vector>
using namespace std;
int main()
{
string str;
vector<string> s;
stack<string> del;
while(cin>>str)
{
char ch = getchar();
if(str == "redo")//恢复
{
if(del.empty())
continue;
string x = del.top();
del.pop();
if(!s.empty())
s.pop_back();
s.push_back(x);
}
else if(str == "undo")//撤销
{
if(str.empty())
continue;
string y = s.back();
del.push(y);
s.pop_back();//碰见撤销,将已入向量的最后一个元素删除
}
else//若没碰到undo和redo就正常入结果向量即可
{
s.push_back(str);
}
if(ch == '\n')
break;
}
for(int i=0;i<s.size();i++)
{
cout<<s[i]<<" ";
}
return 0;
}
vector
a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
a.pop_back(); //删除a向量的最后一个元素
a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素
a.back(); //返回a的最后一个元素
a.front(); //返回a的第一个元素
stack
push(elem); //入栈
pop(); //弹出栈顶元素
top(); //返回栈顶元素
empty(); //判断是否为空
size(); //返回栈的大小