有人要求我在python中创建一个具有以下3个命令的队列:
撤消命令将撤消上一个入队或弹出命令。
这是我写的: 它需要命令的数量,然后是命令本身。 我使用第二个队列来存储第一个队列的先前状态。
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()
示例输入:
10
enqueue 1
enqueue 2
pop
undo
pop
enqueue 3
undo
pop
enqueue 10
pop
示例输出:
1
1
2
10
但是我的问题是,这不支持连续的撤消命令。如何更改它以支持多个连续的撤消命令?
答案 0 :(得分:1)
这里重要的问题,是否需要“可撤销的撤销”? )
无论如何,我强烈建议将逻辑封装到单个类中,当您处理松散的对象时,很容易迷失逻辑。
让我们假设您不需要撤消撤消,这是一个粗略的实现:
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)
想法很简单— 1个双端队列用于任务,1个大小受限(或非大小限制)双端队列,可跟踪如何“撤消”操作。普通的任务双端队列用作FIFO队列-因此您将其附加在一侧,从另一侧弹出。撤消双端队列用作LIFO /堆栈-最后一个上下文是用于撤消事物的内容。
棘手的是,每个操作都会颠倒普通队列和队列队列,也作为参数。即您需要保留弹出式撤销的上下文。