如何解决使用堆栈的撤消/重做实现
我想使用堆栈实现撤消-重做功能。当用户按下 Ctrl+Z 时,最后一个节点将从屏幕上移除。当用户再次按下 Ctrl+Z 时,“last.last”节点将从屏幕上移除,如果他按下 Ctrl+Y 则最后移除的节点将再次显示在屏幕上。
下面是我的代码:
class Node:
def __init__(self,data=None):
self.data = data
self.next = None
self.prev = None
class Stack:
def __init__(self):
self.pointer = None
def push(self,x):
if not isinstance(x,Node):
x = Node(x)
if self.is_empty():
self.pointer = x
undo_stack = Stack()
undo_stack.undo(x)
else:
x.next = self.pointer
self.pointer = x
def pop(self):
if self.is_empty():
print(f'Stack Underflow')
else:
self.pointer = self.pointer.next
def is_empty(self):
return self.pointer is None
def __str__(self):
string = ''
current = self.pointer
while current:
string += f'{current.data}->'
current = current.next
if string:
print(f'Stack Pointer = {self.pointer.data}')
return f'[{string[:-2]}]'
return '[]'
def undo(self,x):
self.push(x)
print(x)
def redo(self,x):
self.pop(x)
print(x)
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
print(stack)
实施
假设我有一个堆栈
堆栈:[5->4->3->2->1]
当我按下 Control+Z
时,undo()
函数调用 pop()
函数并从堆栈中删除最后添加的项目。
5 弹出。 堆栈:[4->3->2->1]
我再次按下 Control+Z
,然后:
4 弹出。 堆栈:[3->2->1]
当我按下 Control+Y
时,redo()
函数被调用,之前删除的项目出现在终端上。
4 推。 堆栈:[4->3->2->1]
我再次按下 Control+Y
,然后
5 推。 堆栈:[5->4->3->2->1]
错误
RecursionError: maximum recursion depth exceeded while calling a Python object
我知道为什么会发生此错误,因为在 push()
中我调用了 undo()
,而在 undo()
中我调用了 push()
。我应该怎么做才能实现撤消-重做功能,我应该创建一个新类并在该类上实现撤消/重做吗?
任何想法/代码都将受到高度赞赏。
解决方法
这里有一些错误。导致无限递归的主要问题是:
undo_stack = Stack()
undo_stack.undo(x)
在这里,您结合了两种不同的方法。您可以要么在您的 UndoRedoStack
类中有两个单独的堆栈,并在调用撤消/重做时来回交换元素,或者您可以有一个双重-节点的链接列表,并在每次要撤消/重做时增加或减少列表。在这里,您似乎两者都在做,并且您在此过程中创建了无限数量的 Stack
。
相反,您只需添加一行:
else:
x.next = self.pointer
self.pointer.prev = x # You forgot this
self.pointer = x
然后,您不需要制作任何其他堆栈。您可以在两个方向上沿链条上下走动。
还有一些其他小错误会阻止课程按预期工作。我已经修复了这些:
class Node:
def __init__(self,data=None):
self.data = data
self.next = None
self.prev = None
def __str__(self):
return f"Node({self.data})"
class Stack:
def __init__(self):
self.pointer = None
def push(self,x):
if not isinstance(x,Node):
x = Node(x)
if self.is_empty():
self.pointer = x
else:
x.next = self.pointer
self.pointer.prev = x
self.pointer = x
def pop(self):
if self.is_empty():
print(f'Stack Underflow')
else:
self.pointer = self.pointer.next
def is_empty(self):
return self.pointer is None
def __str__(self):
string = ''
current = self.pointer
while current:
string += f'{current.data}->'
current = current.next
if string:
print(f'Stack Pointer = {self.pointer.data}')
return f'[{string[:-2]}]'
return '[]'
def undo(self):
x = self.pointer
self.pop()
print(x)
def redo(self):
x = self.pointer.prev
if x is None:
print("nothing to redo")
else:
self.push(x)
print(x)
if __name__ == "__main__":
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
print("stack is:")
print(stack)
print()
stack.undo()
print("after undo:")
print(stack)
print()
stack.redo()
print("after redo:")
print(stack)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。