简体   繁体   English

未直接指定全局变量时如何递增?

[英]How is the global variable being incremented when it's not being directly specified?

I'm working on a small project where I'm implementing a queue as a circular array. 我正在做一个小项目,正在将队列实现为循环数组。 As a challenge, I was assigned to not use any list functions like append when implementing this ADT. 作为挑战,我被分配为在实现此ADT时不使用任何列表功能(如append)。 It's assumed that I only need to resize the queue when it gets full. 假定仅在队列已满时才需要调整其大小。 When I ran my code through a debugger and step through it, I find that the issue revolves around my self.read value (read pointer) which is the global variable in question. 当我通过调试器运行代码并逐步调试时,我发现问题围绕着我的self.read值(读取指针)展开,该值是有问题的全局变量。 This is kind of perplexing to me since neither of my functions that would be affected increments my pointer. 这让我感到困惑,因为我两个受影响的函数都不会增加我的指针。 Could anyone shed some light on this problem for me? 谁能为我阐明这个问题?

This class is coded as: 此类的编码为:

class CircularQueue(object):
    def __init__(self, capacity=2):
        """
        Initialize the queue to be empty with a fixed capacity
        :param capacity: Initial size of the queue
        """
        self.capacity = capacity
        self.size = 0
        self.list = [0] * self.capacity
        self.sum = 0
        self.read = 0
        self.write = 0

    def __eq__(self, other):
        return self.capacity == other.capacity 
               and self.size == other.size 
               and self.read == other.read 
               and self.write == other.write   

    def __str__(self):
        if self.size == 0:
            return "Queue is empty"

        content = ""
        while ((self.read + 1) % self.size) != self.write:

            content = content + str(self.list[self.read]) + " -> "
            self.read = (self.read + 1) % self.size
        content = content[:-3]
        return f"Contents: {content}"
    __repr__ = __str__

The portion that I'm interested in looking at is my enqueue and resize functions: 我感兴趣的部分是我的入队和调整大小功能:

def resize(self):
    bigger = [None] * (self.capacity * 2) #create bigger queue
    b_ind = 0
    read_ptr = self.read
    while read_ptr != (self.write + 1): #iterate through old queue to copy into new queue
        bigger[b_ind] = self.list[read_ptr]
        b_ind += 1
        read_ptr += 1
    self.capacity *= 2 #setting capacity
    self.list = bigger #setting new list as queue
    self.read = 0 #normalize queue
    self.write = b_ind

def enqueue(self, number):

    if self.size == 0: #if queue was originally empty
        self.list[self.read] = number
        self.write += 1
    else:
        self.list[self.write] = number #add onto end of queue
        if ((self.write + 1) % self.capacity == self.read): #resize if queue loops back and the write pointer is the same as the read pointer
            self.resize()
        else:
            self.write = (self.write + 1) % self.capacity #set write pointer
    self.sum += number #add to sum
    self.size += 1  # increment size

This was the test case I ran for my code: 这是我为代码运行的测试用例:

queue = CircularQueue()
queue.enqueue(23)
queue.enqueue(42)
queue.enqueue(2)
queue.enqueue(195)

print(queue)

You mutate the state of your queue when printing . 您可以在打印时更改队列的状态。 print() calls __str__ , and that method alters your state: print()调用__str__ ,该方法会改变您的状态:

self.read = (self.read + 1) % self.size

Use a local variable instead of self.read : 使用局部变量而不是self.read

def __str__(self):
    if self.size == 0:
        return "Queue is empty"

    content = ""
    read = self.read
    while (read % self.capacity) != self.write:
        if content:
            content += ' -> '
        content += str(self.list[read])
        read = (read + 1) % self.capacity
    return f"Contents: {content}"

Note the while loop condition; 注意while循环条件; you want to see if the current read position is not the same as the write position (meaning you can display the current value), not the next position, and you want to wrap round at the capacity . 您想查看当前的读取位置是否与write位置不同(意味着您可以显示当前值),而不是下一个位置,并且希望以该容量来回绕。

I adjusted your separator handling a little to only add the arrow in between values if at least one entry has been added to content already, that avoids having to remove a portion again. 我对分隔符的处理进行了一些调整,以仅在至少一个条目已添加到content ,才在值之间添加箭头,从而避免了再次删除一部分的麻烦。

Demo using the fixed __str__ method (no other changes made): 使用固定的__str__方法的演示(未进行其他更改):

>>> queue = CircularQueue()
>>> print(queue)
Queue is empty
>>> queue.enqueue(23)
>>> print(queue)
Contents: 23
>>> queue.enqueue(42)
>>> print(queue)
Contents: 23 -> 42
>>> queue.enqueue(2)
>>> print(queue)
Contents: 23 -> 42 -> 2
>>> queue.enqueue(195)
>>> print(queue)
Contents: 23 -> 42 -> 2 -> 195

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

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