题目如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Time : 2018/12/22 15:16
@File : dog_cat.py
@Author : frank.chang@shoufuyou.com
猫狗队列 【 题目】 宠物、 狗和猫的类如下:
public class Pet { private String type;
public Pet(String type) { this.type = type; }
public String getPetType() { return this.type; }
}
public class Dog extends Pet { public Dog() { super("dog"); } }
public class Cat extends Pet { public Cat() { super("cat"); } }
实现一种狗猫队列的结构,
要求如下: 用户可以调用add方法将cat类或dog类的
实例放入队列中;
用户可以调用pollAll方法, 将队列中所有的实例按照进队列的先后顺序依次弹出;
用户可以调用pollDog方法, 将队列中dog类的实例按照进队列的先后顺序依次弹出;
用户可以调用pollCat方法, 将队列中cat类的实 例按照进队列的先后顺序依次弹出;
用户可以调用 isEmpty 方法, 检查队列中是否还有dog或cat的实例;
用户可以调用isDogEmpty方法, 检查队列中是否有dog类的实例;
用户可以调用isCatEmpty方法, 检查队列中是否有cat类的实例。
"""
from queue import Queue as _Queue
from datetime import datetime
import time
def _get_curtime():
"""工具类 返回一个时间字符串
返回一个时间字符串
这个如果同时进入 可能 在秒级别的 话,可能会有冲突.
'20181222172324'
:return: str '20181222172324'
"""
t = str(datetime.now())
t1 = t.split('.')[0]
t2 = t1.replace('-', '').replace(":", '').replace(' ', '')
# print(f'curtime:{t2}')
return t2
def get_timestamp():
"""
获取当前时间戳, 毫秒级别, 更小粒度 10**5 10 的5次方级别.
:return:
"""
now = lambda: int(round(time.time() * 100000))
return now()
class Pet:
def __init__(self, type_name):
self.type_name = type_name
def get_type(self):
return self.type_name
class Dog(Pet):
def __init__(self, type_name="dog"):
super().__init__(type_name)
class Cat(Pet):
def __init__(self, type_name="cat"):
super().__init__(type_name)
- 实现思路
"""
解决 方法
设计思路 : 猫狗队列
设计一个 猫队列, 狗队列, 然后每次入队列 给这个猫,狗 打一个标签,表示进入队列 的时间.
出队列的 时候 获取 这个时间进行比较, 时间较小的 一定 是最先进入 队列的, 所以,如果有 一个队列 空了,依次另外一个队列 出队列即可.
"""
class Queue(_Queue):
def __init__(self, maxsize: int = 0) -> None:
super().__init__(maxsize)
def peek(self):
"""
返回队列 队首 元素, 不是出队列
:return:
"""
item = self.queue.popleft()
self.queue.appendleft(item)
return item
class PetEnter:
"""
给每个狗或者猫 打一个时间标签.
"""
def __init__(self, pet, time_):
"""
:param pet: pet dog or cat
:param time_: str 给pet 打一个时间标签
"""
self.pet = pet
self.time_ = time_
def get_pet(self):
return self.pet
def get_time(self):
return self.time_
def getEnterType(self):
return self.pet.get_type()
def __str__(self):
return f"Pet({self.pet.get_type()},{self.time_})"
__repr__ = __str__
class DogCatQueue:
def __init__(self):
self.dog_queue = Queue()
self.cat_queue = Queue()
self.time_ = get_timestamp()
def put(self, pet):
"""
入队列的方法
:param pet:
:return:
"""
cur_time = get_timestamp()
if pet.get_type() == 'dog':
self.dog_queue.put(PetEnter(pet, cur_time))
elif pet.get_type() == 'cat':
self.cat_queue.put(PetEnter(pet, cur_time))
else:
raise TypeError("pet is not dog or not cat ")
def pollAll(self):
"""
将队列中所有的实例按照进队列的先后顺序依次弹出;
:return:
"""
if not self.dog_queue.empty() and not self.cat_queue.empty():
dog_enter = self.dog_queue.peek()
cat_enter = self.cat_queue.peek()
if dog_enter.time_ < cat_enter.get_time():
return self.dog_queue.get().pet
elif dog_enter.time_ > cat_enter.get_time():
return self.cat_queue.get().pet
else:
raise RuntimeError(f"dog_time:{dog_enter.time_} equals cat_time:{cat_enter.time_}")
elif not self.dog_queue.empty():
# return self.dog_queue.get()
return self.dog_queue.get().pet
elif not self.cat_queue.empty():
# return self.cat_queue.get()
return self.cat_queue.get().pet
else:
raise RuntimeError(f"error queue is empty")
def pollDog(self):
"""
将队列中dog类的实例按照进队列的先后顺序依次弹出;
:return:
"""
if not self.dog_queue.empty():
dog = self.dog_queue.get()
return dog.get_pet()
# return dog
def pollCat(self):
"""
:return:
"""
if not self.cat_queue.empty():
cat = self.cat_queue.get()
return cat.get_pet()
def isEmpty(self):
"""
检查队列中是否还有dog或cat的实例;
:return:
"""
if self.cat_queue.empty() and self.dog_queue.empty():
return True
return False
def isDogEmpty(self):
"""
检查队列中是否有dog 类的实例。
:return:
"""
return self.dog_queue.empty()
def isCatEmpty(self):
"""
检查队列中是否有cat类的实例。
:return:
"""
return self.cat_queue.empty()
if __name__ == '__main__':
pass
test = DogCatQueue()
dog1 = Dog("dog")
cat1 = Cat()
dog2 = Dog("dog")
cat2 = Cat()
dog3 = Dog("dog")
cat3 = Cat()
test.put(dog1)
time.sleep(0.1)
test.put(cat1)
time.sleep(0.1)
test.put(dog2)
time.sleep(0.1)
test.put(cat2)
test.put(dog3)
test.put(cat3)
test.put(dog1)
test.put(cat1)
test.put(dog2)
test.put(cat2)
test.put(dog3)
test.put(cat3)
test.put(dog1)
test.put(cat1)
test.put(dog2)
test.put(cat2)
test.put(dog3)
test.put(cat3)
while not test.isDogEmpty():
print(test.pollDog().get_type())
print('***' * 23)
while not test.isEmpty():
print(test.pollAll().get_type())
为方便调试 ,观察是不是这样,可以打印一下,每次dog ,cat 如队列的时间.
class Queue(_Queue):
def __init__(self, maxsize: int = 0) -> None:
super().__init__(maxsize)
def peek(self):
"""
返回队列 队首 元素, 不是出队列
:return:
"""
item = self.queue.popleft()
self.queue.appendleft(item)
return item
class PetEnter:
"""
给每个狗或者猫 打一个时间标签.
"""
def __init__(self, pet, time_):
"""
:param pet: pet dog or cat
:param time_: float 给pet 打一个时间标签
"""
self.pet = pet
self.time_ = time_
def get_pet(self):
return self.pet
def get_time(self):
return self.time_
def getEnterType(self):
return self.pet.get_type()
def __str__(self):
return f"Pet({self.pet.get_type()},{self.time_})"
__repr__ = __str__
class DogCatQueue:
def __init__(self):
self.dog_queue = Queue()
self.cat_queue = Queue()
self.time_ = get_timestamp()
def put(self, pet):
"""
入队列的方法
:param pet:
:return:
"""
cur_time = get_timestamp()
if pet.get_type() == 'dog':
self.dog_queue.put(PetEnter(pet, cur_time))
elif pet.get_type() == 'cat':
self.cat_queue.put(PetEnter(pet, cur_time))
else:
raise TypeError("pet is not dog or not cat ")
def pollAll(self):
"""
将队列中所有的实例按照进队列的先后顺序依次弹出;
:return:
"""
if not self.dog_queue.empty() and not self.cat_queue.empty():
dog_enter = self.dog_queue.peek()
cat_enter = self.cat_queue.peek()
if dog_enter.time_ < cat_enter.get_time():
return self.dog_queue.get()
# return self.dog_queue.get().pet
elif dog_enter.time_ > cat_enter.get_time():
# return self.cat_queue.get().pet
return self.cat_queue.get()
else:
raise RuntimeError(f"dog_time:{dog_enter.time_} equals cat_time:{cat_enter.time_}")
elif not self.dog_queue.empty():
return self.dog_queue.get()
# return self.dog_queue.get().pet
elif not self.cat_queue.empty():
return self.cat_queue.get()
# return self.cat_queue.get().pet
else:
raise RuntimeError(f"error queue is empty")
def pollDog(self):
"""
将队列中dog类的实例按照进队列的先后顺序依次弹出;
:return:
"""
if not self.dog_queue.empty():
dog = self.dog_queue.get()
# return dog.get_pet()
return dog
def pollCat(self):
"""
:return:
"""
if not self.cat_queue.empty():
cat = self.cat_queue.get()
# return cat.get_pet()
return cat
def isEmpty(self):
"""
检查队列中是否还有dog或cat的实例;
:return:
"""
if self.cat_queue.empty() and self.dog_queue.empty():
return True
return False
def isDogEmpty(self):
"""
检查队列中是否有dog 类的实例。
:return:
"""
return self.dog_queue.empty()
def isCatEmpty(self):
"""
检查队列中是否有cat类的实例。
:return:
"""
return self.cat_queue.empty()
if __name__ == '__main__':
pass
test = DogCatQueue()
dog1 = Dog("dog")
cat1 = Cat()
dog2 = Dog("dog")
cat2 = Cat()
dog3 = Dog("dog")
cat3 = Cat()
test.put(dog1)
time.sleep(0.1)
test.put(cat1)
time.sleep(0.1)
test.put(dog2)
time.sleep(0.1)
test.put(cat2)
test.put(dog3)
test.put(cat3)
test.put(dog1)
test.put(cat1)
test.put(dog2)
test.put(cat2)
test.put(dog3)
test.put(cat3)
test.put(dog1)
test.put(cat1)
test.put(dog2)
test.put(cat2)
test.put(dog3)
test.put(cat3)
while not test.isDogEmpty():
enter = test.pollDog()
print(f"{enter.get_pet().get_type()},{enter.get_time()}")
print('***' * 23)
while not test.isEmpty():
enter = test.pollAll()
print(f"{enter.get_pet().get_type()},{enter.get_time()}")
结果如下:
dog,154613228233855
dog,154613228254440
dog,154613228264762
dog,154613228264766
dog,154613228264770
dog,154613228264774
dog,154613228264778
dog,154613228264781
dog,154613228264785
*********************************************************************
cat,154613228243995
cat,154613228264755
cat,154613228264764
cat,154613228264768
cat,154613228264772
cat,154613228264776
cat,154613228264779
cat,154613228264783
cat,154613228264786
<center> 分享快乐,留住感动.22018-12-30 10:03:03 --frank </center>