循环缓冲区Python实现

时间:2013-07-02 19:12:56

标签: python circular-buffer

我为面试问题编写了循环缓冲区的代码。但事实上,两个测试版通过了,其他测试版都失败了。原因失败:索引输出f范围。之后我尝试了几个测试用例来重现故障。不幸的是,他们都没有重现错误。这是代码。

  

实现大小为N的循环缓冲区。允许调用者追加,删除并列出缓冲区的内容。实现缓冲区以实现每个操作的最大性能。

     

“A”n - 将以下n行附加到缓冲区。如果缓冲区已满,则替换旧条目   “R”n - 删除缓冲区的前n个元素。这些n个元素是当前元素中最早添加的元素   “L” - 按插入时间的顺序列出缓冲区的元素   “Q” - 退出。

class circbuffer():

    #initialization
    def __init__(self,size):
            self.maximum=size
            self.data=[]
            self.current=0


    #appending when the buffer is not full
    def append(self,x):
            if len(self.data)==self.maximum:
                    self.current=0
                    self.data[self.current]=x
                    self.current=(self.current+1)%self.maximum
                    self.__class__=bufferfull
            else:
                    self.data.append(x)

    def remove(self,x):
            if self.data:
                    self.data.pop(0)

    def cget(self):
            return self.data

class bufferfull:

    def append(self,x):
            if len(self.data)<self.maximum:
                    self.data.insert(self.current, x)
            else:
                    self.data[self.current]=x
            self.current=(self.current+1)%self.maximum

    def remove(self,x):
            if self.data:
                    if self.current>len(self.data):
                            self.current=0
                    self.data.pop(self.current)

    def cget(self):
            return self.data[self.current:]+self.data[:self.current]
n=input()

buf=circbuffer(n)
outputbuf=[]

while True:
    com=raw_input().split(' ')
    if com[0]=='A':
            n=int(com[1])
            cominput=[]
            for i in xrange(n):
                    cominput.append(raw_input())
            for j in cominput:
                    buf.append(j)
    elif com[0]=="R":
            n=int(com[1])
            for i in range(n):
                    buf.remove(i)
    elif com[0]=="L":
            for i in buf.cget():
                    outputbuf.append(i)
    elif com[0]=="Q":
            break

for i in outputbuf:
    print i

错误指向类bufferfull中的self.data.pop(self.current)。我无法从面试人员那里得到测试数据。我试图自己提出测试用例来重现错误。

任何见解?

2 个答案:

答案 0 :(得分:1)

这里有一个错误:

def remove(self,x):
        if self.data:
                if self.current>len(self.data):
                        self.current=0
                self.data.pop(self.current)

如果self.current == len(self.data),您将尝试弹出不存在的元素。

作为一般性评论,你的实施过于复杂,因此我的书中得分不高(其他人可能会有不同的看法)。 @ 9000对你的问题的评论总结得很好:

  

保持简单。当你在相同数量的行中直截了当时,不要聪明。您只需要一个头指针,一个尾指针和一个固定大小的列表。你不需要任何花哨的元编程东西。 - @ 9000

答案 1 :(得分:1)

您似乎试图使用下面的代码停止index out of range错误,但您检查的情况是错误的。

if self.current > len(self.data):
    self.current = 0
self.data.pop(self.current)

如果您致电self.data.pop(len(self.data)),您肯定会收到该错误,因为列表是0索引的。你可能意味着:

if self.current >= len(self.data):
    self.current = 0
self.data.pop(self.current)