简体   繁体   English

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

[英]Removing 2nd item from a queue, using another queue as an ADT

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)

The remove_2nd class is basically a queue except if the length of the queue is greater than two, then you remove the 2nd item every dequeue. remove_2nd类基本上是一个队列,除非队列的长度大于2,则在每次出队时都删除第二个项。 If it isn't then you do the same as a normal queue. 如果不是,则与普通队列相同。 I am only allowed to use the methods in the queue to finish remove_2nd. 我只允许使用队列中的方法来完成remove_2nd。

My algorithm: 我的算法:

If queue is bigger than two: 如果队列大于两个:

Lets say my queue is 1 2 3 4 可以说我的队列是1 2 3 4

I would first remove the first item so it becomes 我会先删除第一个项目

2 3 4 2 3 4

I would then remove the 2nd item and that will be the returned value, so then it will be 然后,我将删除第二个项目,这将是返回值,因此它将是

3 4 3 4

I would then add back the first item as wanted 然后,我将根据需要添加回第一项

1 3 4 1 3 4

The problem is, I don't know how to add it back. 问题是,我不知道如何将其重新添加。 Enqueue puts it at the end, so basically it would be 3 4 1. I was thinking of reversing the 3 4, but I don't know how to do that either. Enqueue将其放在最后,因此基本上是3 41。我正在考虑反转3 4,但是我也不知道该怎么做。 Any help? 有什么帮助吗?

Just want to point out, I'm not allowed to call on _contents or allowed to create my own private variable for the remove_2nd class. 只是想指出,我不允许调用_contents或为remove_2nd类创建自己的私有变量。 This should strictly be done using the queue adt 这应该严格使用队列adt完成

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

To get the queue back in the right order after removing the first two elements, you'll need to remove all the other elements as well. 要在删除前两个元素后以正确的顺序返回队列,您还需要删除所有其他元素。 Once the queue is empty, you can add back the first element and all the other elements one by one. 队列为空后,您可以一个一个地添加回第一个元素和所有其他元素。

How exactly you keep track of the values you're removing until you can add them again is a somewhat tricky question that depends on the rules of your assignment. 在重新添加之前,如何精确地跟踪要删除的值是一个棘手的问题,具体取决于分配规则。 If you can use Python's normal types (as local variables, not as new attributes for your class), you can put them in a list or a deque from the collections module. 如果可以使用Python的普通类型(作为局部变量,而不是类的新属性),则可以将它们放在collections模块的列表或deque But you can also just use another Queue instance (an instance of the base type, not your subclass). 但是,您也可以只使用另一个Queue实例(基类型的实例,而不是您的子类)。

Try something like this in your else clause: 在您的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

As I commented in the code, Queue.dequeue(self) can be written more "pythonically" using the super builtin. 正如我在代码中评论的那样,可以使用super内置函数更加“ Python化地”编写Queue.dequeue(self) The exact details of the call depend on which version of Python you're using (Python 3's super is much fancier than Python 2's version). 调用的确切细节取决于您使用的是哪个版本的Python(Python 3的super版本比Python 2的super得多)。

In Python 2, you have to explicitly pass self and your current class, so the call would be super(self, dequeue_2nd).dequeue() . 在Python 2中,您必须显式传递self和当前类,因此调用将是super(self, dequeue_2nd).dequeue() In Python 3, you simply use super().dequeue() and it "magically" takes care of everything (in reality, the compiler figures out the class at compile time, and adds some extra code to let it find self at run time). 在Python 3中,您只需使用super().dequeue() “神奇地”处理所有事情(实际上,编译器会在编译时找出该类,并添加一些额外的代码以使其在运行时self找到self )。

For your simple code with only basic inheritance, there's no difference between using super or explicitly looking up the base class by name. 对于仅具有基本继承的简单代码,使用super或通过名称显式查找基类之间没有区别。 But in more complicated situations, using super is very important. 但是在更复杂的情况下,使用super非常重要。 If you ever use multiple inheritance, calling overridden methods with super is often the only way to get things to work sanely. 如果您曾经使用多重继承,那么使用super调用重写的方法通常是使事情正常运行的唯一方法。

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

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