撤销/恢复操作具有广泛的用途,比如 word 文档中输入一个单词,可以点撤销,然后可以再恢复。

编程实现如下功能:  从标准输入读取到一个字符串,字符串可包含0个或多个单词,单词以空格或者tab分隔; 如果遇到 “undo” 字符串,表示”撤销”操作,前一个字符串被撤销掉; 如果遇到”redo”字符串,表示恢复刚才撤销掉的字符串.

例如:   输入字符串 “hello undo redo world.”,  对字符串中的 undo 和 redo 处理后, 最终输出的结果为 “hello world.”

双栈解法

先初始化两个栈 stack 和 redo,然后利用双栈求解。遍历词表:

  1. 遇到普通词就压入stack,并清空redo栈,因为此时写入了一个新词,再往前的词已经找不回来了;
  2. 遇到undo就从stack中弹栈至redo;
  3. 遇到redo就从redo中弹栈至stack。
 
 
import java.util.*;
 
public class Test {
 
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String str=scanner.nextLine();
        Stack stack=ctrlZ(str);
        System.out.println(String.join(" ", stack));
    }
 
    private static Stack ctrlZ(String str) {
        Stack<String> stack = new Stack<String>();
        Stack<String> redoStack = new Stack<String>();
        List<String> list = new ArrayList<>(Arrays.asList(str.replace("\t"" ").split(" ")));
        for (int i = 0; i < list.size(); i++) {
            if ("undo".equals(list.get(i))){
                if (!stack.empty()){
                    redoStack.push(stack.pop());
                }
            }else if("redo".equals(list.get(i))){
                if(!redoStack.empty()){
                    stack.push(redoStack.pop());
                }
            }else{
                redoStack.clear();
                stack.push(list.get(i));
            }
 
        }
        return stack;
    }
}