使用另一个队列作为ADT从队列中删除第二个项目

时间:2017-05-29 05:35:47

标签: python abstract-data-type

class Queue:

    def __init__(self):
        self._contents = []

    def enqueue(self, obj):
        self._contents.append(obj)

    def dequeue(self):
        return self._contents.pop(0)

    def is_empty(self):
        return self._contents == []

class remove_2nd(Queue):

    def dequeue(self):

        first_item = Queue.dequeue(self)
        # Condition if the queue length isn't greater than two
        if self.is_empty():
            return first_item
        else:
            # Second item to return
            second_item = Queue.dequeue(self)
            # Add back the first item to the queue (stuck here)

remove_2nd类基本上是一个队列,除非队列长度大于2,然后每次出列都删除第二个项目。如果不是,则执行与普通队列相同的操作。我只允许使用队列中的方法来完成remove_2nd。

我的算法:

如果队列大于2:

让我们说我的队列是1 2 3 4

我会首先移除第一个项目,使其成为

2 3 4

然后我会删除第二个项目,这将是返回的值,因此它将是

3 4

然后我会添加第一个想要的项目

1 3 4

问题是,我不知道如何添加它。 Enqueue将它放在最后,所以基本上它将是3 4 1.我正在考虑扭转3 4,但我不知道该怎么做。有帮助吗?

只是想指出,我不允许调用_contents或允许为remove_2nd类创建自己的私有变量。这应该严格使用队列adt

来完成

2 个答案:

答案 0 :(得分:1)

def insert(self,position,element):
    self._contents.insert(position,element)

答案 1 :(得分:0)

要在删除前两个元素后以正确的顺序恢复队列,您还需要删除所有其他元素。队列为空后,您可以逐个添加第一个元素和所有其他元素。

在您再次添加这些值之前,如何准确跟踪要删除的值是一个有点棘手的问题,取决于您的分配规则。如果您可以使用Python的常规类型(作为局部变量,而不是类的新属性),则可以将它们放在列表中或deque模块中的collections中。但是你也可以使用另一个Queue实例(基类型的实例,而不是你的子类)。

else子句中尝试这样的事情:

second_item = Queue.dequeue(self)   # note, this could be written super().dequeue()

temp = Queue()
while not self.is_empty():
    temp.enqueue(Queue.dequeue(self))

self.enqueue(first_item)
while not temp.is_empty()
    self.enqueue(temp.dequeue())

return second_item

正如我在代码中评论的那样,Queue.dequeue(self)可以使用super内置函数更加“pythonically”编写。调用的确切细节取决于您使用的Python版本(Python 3的super比Python 2的版本更加出色)。

在Python 2中,您必须明确传递self和当前的类,因此调用将是super(self, dequeue_2nd).dequeue()。在Python 3中,您只需使用super().dequeue()并且它“神奇地”处理所有事情(实际上,编译器在编译时计算出类,并添加一些额外的代码以使其找到self at运行时间)。

对于只有基本继承的简单代码,使用super或按名称显式查找基类没有区别。但在更复杂的情况下,使用super非常重要。如果您使用多重继承,则使用super调用重写方法通常是让事情正确运行的唯一方法。