java - 为数组实现撤销和重做

标签 java arrays algorithm collections

我今天在 Java 面试中遇到了这个问题。

我必须实现一个集合,它是一个数组并具有只能在数组末尾执行的 adddelete 方法。

除此之外,我还必须实现另外两个方法,即 undoredo 方法,它们只能执行一次。

例如:

令 x 为包含 {1,5,7,9} 的数组。

现在我在其中添加 {44,66,77} 并使其成为 {1,5,7,9,44,66,77}

现在当我撤消它时,数组应该删除 {44,66,77}。如果我之后重做,它应该回到 {1,5,7,9,44,66,77}

对于删除也类似。

在复杂性和内存方面实现此目标的最佳方法是什么?

我对面试官的解答:

  1. 制作一个字符串字段,用于存储最后一次操作,即“添加”/“删除”。
  2. 和一个 hashmap,它将 key 存储为数组的索引,将 value 存储为数组的索引值。

根据面试官的说法,这是一个完全错误的解决方案。

最佳答案

我会这样解决。基本上,会有三个列表。

  • 具有实际值的列表
  • 撤消列表 带有Command 接口(interface)的实例
  • Redo list 带有 Command 接口(interface)的实例(可选,解释如下)

    public interface Command {
        void do();
        void undo();
    }
    

将有两个Command 实现:AddCommandRemoveCommand

  • add() 上,创建了 AddCommand 的新实例并将其添加到撤消列表。然后我们调用该命令的do(),它修改实际值并存储添加项的index
  • remove() 上,创建了 RemoveCommand 的新实例并将其添加到撤消列表。然后我们调用此命令的do(),它修改实际值并存储索引和删除项的值。
  • undo() 上,我们从undo 列表 中提取最后一个命令并执行该命令的undo() 方法。命令推送到重做列表AddCommandRemoveCommand 的撤消方法可还原更改。
  • redo() 上,我们从 redo 列表 中提取最后一条命令并再次执行 do() 方法。拉出的命令被添加到撤消列表

另一个优化是删除redo list 并使用undo index 代替。在这种情况下,当您undo() 时,您不需要从列表中删除/添加值,而只需将undo 索引 减一。同样,redo() 会将其增加 1。

因此最终的解决方案将包含值列表撤消列表和一个索引值

更新:

对于最简单的情况,只需要一个undo()/redo() 操作,解决方案看起来会更简单。不用undo listindex,存储最新的命令实例就足够了。因此,您将拥有一个值列表和一个最后撤消命令的实例。

关于java - 为数组实现撤销和重做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22412569/

相关文章:

c# - 读取包含大量元素的字符串列表 C#

algorithm - 求 10^5 阶完全图的 EMST 的最简单、最容易的算法是什么

Java - 如何降低 float 精度?

php - 如果之前的字符串与当前字符串相似,则不回显字符串

JAVA 8 : RowMapper

c - C 中的二维数组

algorithm - 实现此算法的最佳方法是什么?

algorithm - 整数 数字的平方根

java - 分块传输编码时如何使用 HttpsUrlconnection 读取响应

java.lang.IllegalStateException : File has already been moved - cannot be transferred again 错误