Python 使用堆栈实现撤消/重做
我想使用堆栈实现撤销重做功能。当用户按下Ctrl+Z时,最后一个节点将从屏幕上删除。当用户再次按Ctrl+Z时,“last.last”节点将从屏幕上删除,如果用户按Ctrl+Y,则最后删除的节点将再次显示在屏幕上 下面是我的代码:Python 使用堆栈实现撤消/重做,python,data-structures,stack,undo-redo,getch,Python,Data Structures,Stack,Undo Redo,Getch,我想使用堆栈实现撤销重做功能。当用户按下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 Stac
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]
错误
我知道为什么会发生此错误,因为在push()
中我调用了undo()
,在undo()
中我调用了push()
。我应该如何实现撤销重做功能,我应该创建一个新类并在该类上实现撤销/重做吗
任何想法/代码都是非常值得欣赏的。这其中有一些错误。导致无限递归的主要问题是:
undo_stack=stack()
撤消堆栈。撤消(x)
在这里,您将结合两种不同的方法。您可以在UndoRedoStack
类中有两个单独的堆栈,并在调用undo/redo时来回交换元素,也可以有一个节点的双链接列表,并在每次要撤消/重做时递增或递减该列表。在这里,您似乎同时做了这两件事,并且在这个过程中创建了无限多的堆栈
相反,您只需添加一行:
其他:
x、 next=self.pointer
self.pointer.prev=x#你忘了这个
self.pointer=x
然后,您不需要进行任何其他堆栈。你可以沿着链条上下走两个方向
还有一些其他的小错误,可能会妨碍全班按计划工作。我已经把它们修好了:
类节点:
def uuu init uuuu(self,data=None):
self.data=数据
self.next=无
self.prev=无
定义(自我):
返回f“节点({self.data})”
类堆栈:
定义初始化(自):
self.pointer=None
def推送(自,x):
如果不是isinstance(x,节点):
x=节点(x)
如果self.is_为空():
self.pointer=x
其他:
x、 next=self.pointer
self.pointer.prev=x
self.pointer=x
def pop(自我):
如果self.is_为空():
打印(f‘堆栈下溢’)
其他:
self.pointer=self.pointer.next
def为空(自身):
返回self.pointer为None
定义(自我):
字符串=“”
当前=自身指针
当前:
字符串+=f'{current.data}->'
当前=当前。下一步
如果字符串:
打印(f'Stack Pointer={self.Pointer.data}')
返回f'[{string[:-2]}]'
返回“[]”
def撤消(自我):
x=自指针
self.pop()
打印(x)
def重做(自我):
x=self.pointer.prev
如果x为无:
打印(“无需重做”)
其他:
自推(x)
打印(x)
如果名称=“\uuuuu main\uuuuuuuu”:
stack=stack()
堆栈推送(1)
堆栈推送(2)
堆栈推送(3)
堆栈推送(4)
堆栈推送(5)
打印(“堆栈为:”)
打印(堆栈)
打印()
stack.undo()
打印(“撤消后:”)
打印(堆栈)
打印()
stack.redo()
打印(“重做后:”)
打印(堆栈)
也许您正在实现一个堆栈作为一个学习练习-但为什么不使用collections.deque?这个想法不是关于实现collections.deque
或构建您自己的定制堆栈
类。不过,我们也可以使用它。编辑:我更喜欢构建自己的堆栈类,并在上面实现撤销重做功能。
RecursionError: maximum recursion depth exceeded while calling a Python object