简体   繁体   English

在python中实现支持撤消功能的队列

[英]Implement a queue in python that supports undo feature

I've been asked to create a queue in python that has these 3 commands: 我被要求在python中创建一个具有以下3个命令的队列:

  • enqueue 排队
  • pop 流行的
  • undo 解开

The undo command will undo the previous enqueue or pop command. 撤消命令将撤消先前的入队或弹出命令。

Here's what I've written: It takes the number of commands and then the commands themselves. 这是我写的内容:它需要命令的数量,然后是命令本身。 I used the second queue to store the previous state of the first queue. 我使用第二个队列来存储第一个队列的先前状态。

from collections import deque

queue_1 = deque()
queue_2 = deque()
num_of_commands = int(input())
commands = []
for i in range(num_of_commands):
    commands.append(input())

for i in range(len(commands)):
    queue_2 = queue_1.copy()
    if 'enqueue' in commands[i]:
        queue_1.append(int((commands[i].split())[1]))
    elif 'pop' in commands[i]:
        if len(queue_1) != 0:
            print(queue_1.popleft())
    if i < len(commands) - 1:
        if ((commands[i + 1].split())[0]) == 'undo':
            queue_1 = queue_2.copy()

Example input: 输入示例:

10
enqueue 1
enqueue 2
pop
undo
pop
enqueue 3
undo
pop
enqueue 10
pop

Example output: 输出示例:

1
1
2
10

But my problem is that this doesn't support consecutive undo commands. 但是我的问题是,这不支持连续的撤消命令。 How can I change it to support multiple consecutive undo commands? 如何更改它以支持多个连续的撤消命令?

Important question here, if you need to have "undoable undo"? 这里的重要问题是,是否需要“可撤消撤消”? )

In any case, I highly recommend encapsulating logic into single class, it's easy to get lost with logic while you're manipulating loose objects. 无论如何,我强烈建议将逻辑封装到单个类中,当您处理松散的对象时,很容易迷失逻辑。

Lets assume you don't need to undo undos, a little bit sketchy implementation: 让我们假设您不需要撤消撤消,这是一个粗略的实现:

class QueueWithUndo:
    def __init__(self, history=10):
        self.q = deque()
        self.undo_q = deque(maxlen=history)

    def enqueue(self, task):
        self.undo_q.append((self.q.pop, ))
        self.q.append(task)

    def pop(self):
        result = self.q.popleft()
        self.undo_q.append((self.q.append, result))
        return result

    def undo(self):
        op, *task = self.undo_q.pop()
        op(*task)

Idea is simple — 1 deque for tasks, 1 size-restricted (or not) deque that keeps tracking on how to "undo" operations. 想法很简单-1个双端队列用于任务,1个大小受限制(或不受限)的双端队列一直跟踪如何“撤消”操作。 Normal task deque is used as FIFO queue — so you append on one side, pop from opposite. 普通的任务双端队列用作FIFO队列-因此您将其附加在一侧,从另一侧弹出。 Undo deque is used as LIFO/stack — last context is what used to undo things. 撤消双端队列用作LIFO /堆栈-最后一个上下文是用于撤消事物的内容。

The tricky thing is that normal and unto queues are inverted every operation, as well as arguments. 棘手的是,每个操作以及参数都会颠倒正常队列和正常队列。 Ie you need to keep context for pop undo. 即,您需要保留弹出撤销的上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM