首页 > 试题广场 >

撤销与恢复

[编程题]撤销与恢复
  • 热度指数:3074 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解
撤销/恢复操作具有广泛的用途,比如word文档中输入一个单词,可以点撤销,然后可以再恢复。
编程实现如下功能:  从标准输入读取到一个字符串,字符串可包含0个或多个单词,单词以空格或者tab分隔; 如果遇到 "undo" 字符串,表示"撤销"操作,前一个字符串被撤销掉; 如果遇到"redo"字符串,表示恢复刚才撤销掉的字符串.
例如:   输入字符串 "hello undo redo world.",  对字符串中的 undo 和 redo 处理后, 最终输出的结果为 "hello world."

输入描述:
一行字符串: 包含0个或多个单词,单词以空格或者tab分隔


输出描述:
一行字符串: 由0个或多个单词组成,单词以空格分隔
示例1

输入

hello undo redo world.

输出

hello world.

redo只有遇到undo才有意义,undo如果没被redo抵消,则会撤销在redo出现前的字符串

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] arr = scanner.nextLine().split(" ");
        Stack stack = new Stack();
        StringBuilder builder = new StringBuilder();
        for(String s:arr){
            // 遇到普通字符入栈
            // 遇到undo,暂时放入栈中
            // 遇到redo,碰到undo则抵消
            if(s.equals("redo")){
                if(stack.peek().equals("undo")){
                    stack.pop();
                }
            }else{
                stack.push(s);
            }
        }
        while(!stack.isEmpty()){
            String s = stack.pop();
            if(s.equals("undo")){
                stack.pop();
            }else{
                builder.insert(0," "+s);
            }
        }
        System.out.println(builder.substring(1).toString());
    }
}
发表于 2024-08-30 11:27:57 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()){
            ctrlZ(sc.nextLine());
        }
    }

    private static void ctrlZ(String str) {

        List<String> list = new ArrayList<>(Arrays.asList(str.replace("\t", " ").split(" ")));

        Deque<String> deque = new LinkedList<>();

        for (int i=0;i<list.size();i++){
            if("undo".equals(list.get(i))){
                list.remove(i--);
                if(i>=0){
                    deque.push(list.get(i));
                    list.remove(i--);
                }
            }else if("redo".equals(list.get(i))){
                list.remove(i);
                if(!deque.isEmpty()){
                    list.add(i++,deque.pop());
                }
                i--;
            }else{
                deque.clear();
            }
        }
        System.out.println(String.join(" ",list));
    }
}
提交一直是差一个测试点没通过,后来发现是恢复操作添加元素时需要把位置加1,因为下面为了不漏过redo后面的单词,所以有个i--,所以位置不加1的话就会再次访问到添加的这个单词,这样就会触发else条件,把原先的deque清空(本不该清空),就会导致不正确的结果出现。

发表于 2022-03-30 19:07:43 回复(0)
请指教
public class UndoRedo {
    public static void main(String[] args) throws InterruptedException {
        // 创建存储对外显示的字符串的栈集合 usefulWords
        Stack<String> usefulWords = new Stack<> ();
        // 创建储存删除的字符串的栈集合 uselessWords
        Stack<String> uselessWords = new Stack<> ();
        // 创建scanner对象获取用户输入的字符串
        Scanner scanner = new Scanner (System.in);
        // 创建输入的死循环,可暂用 不输入 表示结束输入
        while (true) {
            // 友好提示
            System.out.print ("请输入:");
            String input= scanner.nextLine ();
            // 不输入表示结束循环
            if (input == null || input.equals ("")) {
                System.out.println ("感谢使用,Bye");
                return;
            }
            // 切割字符串
            String[] inputWords = input.split (" ");
            for (String inputWord : inputWords) {
                // 判断输入的字符串值 undo redo  其他三种情况
                if ("undo".equals (inputWord)) {
                    // usefulWords 非空则移除 usefulWords 栈顶的元素,添加到 uselessWords 集合
                    if (!usefulWords.empty ()) {
                        uselessWords.push (usefulWords.pop ());
                    }
                } else if ("redo".equals (inputWord)) {
                    // uselessWords 非空则移除 uselessWords 栈顶的元素,添加到 usefulWords 集合
                    if (!uselessWords.empty ()) {
                        usefulWords.push (uselessWords.pop ());
                    }
                } else {
                    // 把输入的字符串添加到 usefulWords 集合中,加空格为排版~~
                    usefulWords.push (inputWord + " ");
                }
            }

            // 显示输入的数据
            System.out.print ("目前文章:");
            usefulWords.forEach (System.err::print);

            // 为显示效果,睡 0.1 秒再执行下一次循环
            Thread.sleep (100);
            // 添加空格排版~~~
            System.out.println ();
        }
    }
}

编辑于 2022-01-22 23:02:07 回复(1)