Python 使用堆栈实现撤消/重做

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

我想使用堆栈实现撤销重做功能。当用户按下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]

错误 我知道为什么会发生此错误,因为在
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