【问题标题】:Removing 2nd item from a queue, using another queue as an ADT从队列中删除第二个项目,使用另一个队列作为 ADT
【发布时间】:2017-05-29 05:35:47
【问题描述】:
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,然后在每次出队时删除第 2 个项目。如果不是,那么您将执行与普通队列相同的操作。我只被允许使用队列中的方法来完成 remove_2nd。

我的算法:

如果队列大于两个:

假设我的队列是 1 2 3 4

我会先删除第一项,这样它就变成了

2 3 4

然后我会删除第二个项目,这将是返回值,那么它将是

3 4

然后我会根据需要添加回第一项

1 3 4

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

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

【问题讨论】:

    标签: python abstract-data-type


    【解决方案1】:
    def insert(self,position,element):
        self._contents.insert(position,element)
    

    【讨论】:

    • 您在列表中的任意位置添加一个元素。
    • 我很确定他们的提问者根本不允许对self._contents 进行任何操作。他们只能使用Queue定义的方法,不能访问它的“私有”数据。
    【解决方案2】:

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

    在您可以再次添加之前,您如何准确地跟踪要删除的值是一个有点棘手的问题,具体取决于您的分配规则。如果您可以使用 Python 的普通类型(作为局部变量,而不是作为类的新属性),您可以将它们放在一个列表或来自 collections 模块的 deque 中。但您也可以只使用另一个 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)。

    对于只有基本继承的简单代码,使用super 或通过名称显式查找基类没有区别。但在更复杂的情况下,使用super 非常重要。如果您曾经使用过多重继承,那么使用 super 调用覆盖的方法通常是让事情正常工作的唯一方法。

    【讨论】:

    • 非常感谢,也感谢 super() 提示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多