猫狗队列

48 篇文章 0 订阅

题目:
宠物,猫,狗如下

class Pet:
    def __init__(self, no):
        self.no = no

    
    def get_type(self):
        return self.type

    
    def get_no(self):
        return self.no


class Cat(Pet):
    def __init__(self, no):
        self.type = 'cat'
        Pet.__init__(self, no)


class Dog(Pet):
    def __init__(self, no):
        self.type = 'dog'
        Pet.__init__(self, no)

实现一个猫狗队列,支持:
1) add猫或狗
2) poll,出队一个宠物
3)poll_dog,出队一只狗
4)poll_cat,出队一只猫
5) empty,队列是否为空
6)dog_empty,狗队是否为空
7)cat_empty,猫队是否为空

思路:
一个办法是猫,狗各维护一个队列,但问题是poll的时候怎么知道poll猫还是poll狗。
简单的办法就是想办法给类增加一个时间戳,根据时间戳判断入队顺序。
在不改变给定的类的情况下,一种方法就是增加一个新类:

class PetQueueItem:
    def __init__(self, pet, timestamp):
        self.pet = pet
        self.timestamp = timestamp


    def get_pet(self):
        return self.pet


    def get_timestamp(self):
        return self.timestamp


    def get_type(self):
        return self.pet.get_type()

猫狗队列实现如下:

class DogCatQueue:
    def __init__(self):
        self.dog_queue = []
        self.cat_queue = []
        self.timestamp = 0


    def add(self, pet):
        if pet.get_type() == 'dog':
            self.dog_queue.append(PetQueueItem(pet, self.timestamp))
        elif pet.get_type() == 'cat':
            self.cat_queue.append(PetQueueItem(pet, self.timestamp))
        else:
            raise Exception('Error pet type')

        self.timestamp += 1


    def poll(self):
        if self.empty():
            raise Exception('Queue is empty')

        if self.dog_empty():
            return self.cat_queue.pop(0)

        if self.cat_empty():
            return self.dog_queue.pop(0)

        if self.dog_queue[0].get_timestamp() < self.cat_queue[0].get_timestamp():
            return self.dog_queue.pop(0)
        else:
            return self.cat_queue.pop(0)


    def poll_dog(self):
        if self.dog_empty():
            raise Exception('Dog Queue is empty')

        return self.dog_queue.pop(0)


    def poll_cat(self):
        if self.cat_empty():
            raise Exception('Cat Queue is empty')

        return self.cat_queue.pop(0)


    def empty(self):
        return self.dog_empty() and self.cat_empty()


    def dog_empty(self):
        return len(self.dog_queue) == 0


    def cat_empty(self):
        return len(self.cat_queue) == 0

测试:

def get_rand_no(d, maxno):
    while True:
        no = random.randint(0, maxno)
        if no not in d:
            d[no] = True
            return no


def test_queue(times, maxno):
    cat_queue = []
    dog_queue = []
    queue = []
    cat_dog_queue = DogCatQueue()
    no_dir = {}

    for _ in range(times):
        op = random.randint(0, 8)
        if op == 0:
            # add dog
            no = get_rand_no(no_dir, maxno)
            dog_queue.append(Dog(no))
            queue.append(Dog(no))
            cat_dog_queue.add(Dog(no))
        elif op == 1:
            # add cat
            no = get_rand_no(no_dir, maxno)
            cat_queue.append(Cat(no))
            queue.append(Cat(no))
            cat_dog_queue.add(Cat(no))
        elif op == 2:
            # poll dog
            if len(dog_queue) == 0:
                if not cat_dog_queue.dog_empty():
                    raise Exception('Error dog queue')
            else:
                d1 = dog_queue.pop(0)
                d2 = cat_dog_queue.poll_dog()
                for i in range(len(queue)):
                    if queue[i].get_no() == d1.get_no():
                        queue.pop(i)
                        break

                if d1.get_no() != d2.get_pet().get_no():
                    raise Exception('Error poll dog')
                print('poll dog', d1.get_no())
                no_dir.pop(d1.get_no())
        elif op == 3:
            # poll cat
            if len(cat_queue) == 0:
                if not cat_dog_queue.cat_empty():
                    raise Exception('Error cat queue')
            else:
                c1 = cat_queue.pop(0)
                c2 = cat_dog_queue.poll_cat()
                for i in range(len(queue)):
                    if queue[i].get_no() == c1.get_no():
                        queue.pop(i)
                        break

                if c1.get_no() != c2.get_pet().get_no():
                    raise Exception('Error poll cat')
                print('poll cat', c1.get_no())
                no_dir.pop(c1.get_no())
        elif op == 4:
            # poll
            if len(queue) == 0:
                if not cat_dog_queue.empty():
                    raise Exception('Error queue')
            else:
                p = queue.pop(0)
                if len(cat_queue) != 0 and p.get_no() == cat_queue[0].get_no():
                    cat_queue.pop(0)
                else:
                    dog_queue.pop(0)
                p2 = cat_dog_queue.poll()
                if p.get_no() != p2.get_pet().get_no():
                    raise Exception('Error poll')
                print('poll pet', p.get_no())
                no_dir.pop(p.get_no())

        elif op == 5:
            # empty
            b1 = len(dog_queue) == 0 and len(cat_queue) == 0
            b2 = len(queue) == 0
            b3 = cat_dog_queue.empty()
            if b1 != b2 or b2 != b3:
                raise Exception('Error empty')
        elif op == 6:
            # dog empty
            b1 = len(dog_queue) == 0
            b2 = cat_dog_queue.dog_empty()
            if b1 != b2:
                raise Exception('Error dog empty')
        elif op == 7:
            # cat empty
            b1 = len(cat_queue) == 0
            b2 = cat_dog_queue.cat_empty()
            if b1 != b2:
                raise Exception('Error cat empty')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值