【算法题】04-猫狗队列
题目
宠物猫和狗的类如下:
public static class Pet {
private String type;
public Pet(String type) {
this.type = type;
}
public String getPetType() {
return this.type;
}
}
public static class Dog extends Pet {
public Dog() {
super("dog");
}
}
public static class Cat extends Pet {
public Cat() {
super("cat");
}
}
实现个猫狗队列的结构,需求如下:
- 用户可以调用add方法将cat类或dog类的实例放入队列中
- 用户可以调用pullAll方法,将队列中所有的实例安装进队列的先后顺序依次弹出
- 用户可以调用pollDog方法,将队列中的dog类的实例按照进队列的先后顺序依次弹出
- 用户可以调用pollCat方法,将队列中的cat类的实例按照进队列的先后顺序依次弹出
- 用户可以调用isDogEmpty方法,检查队列中是否有dog类的实例
- 用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例
思路
将不同的实例盖上时间戳的方法,但是又不能改变用户本身的类,所以定义一个新的类
/**
* @Desc 新增一个类 为每个对象加上一个时间戳计数
* @author sangliping
*
*/
public static class PetEnterQueue {
private Pet pet;
private long count;
public PetEnterQueue(Pet pet, long count) {
this.pet = pet;
this.count = count;
}
public Pet getPet() {
return this.pet;
}
public long getCount() {
return this.count;
}
public String getEnterPetType() {
return this.pet.getPetType();
}
}
我们实现的队列其实就是PetEnterQueue类的实例,大体来说,首先要有一个不断累加的数据项,用来表示实例进队的时间,同时有两个队列,一个是只放dog类实例的队列dogQ另一个是只放cat类的实例的队列catQ.在加入实例时,
加入实例时,如果是dog,就盖上时间戳,生成对应的PetEnterQueue类的实例;然后放入dogQ;如果实例是cat,就盖上时间戳,生成对应的PetEnterQueue类的实例,然后放入catQ.
只想弹出dog类的实例时,从dogQ里不断弹出即可,弹出cat同理.
按实际顺序弹出时,因为dogQ的队列头表示所有dog实例中最早进队额的实例,catQ同理,这样的话比较队头元素的时间戳,谁早就弹出谁。
解题
package com.zixin.learn;
import java.util.LinkedList;
import java.util.Queue;
public class DogCatQueue {
public static class Pet {
private String type;
public Pet(String type) {
this.type = type;
}
public String getPetType() {
return this.type;
}
}
public static class Dog extends Pet {
public Dog() {
super("dog");
}
}
public static class Cat extends Pet {
public Cat() {
super("cat");
}
}
/**
* @Desc 新增一个类 为每个对象加上一个时间戳计数
* @author sangliping
*
*/
public static class PetEnterQueue {
private Pet pet;
private long count;
public PetEnterQueue(Pet pet, long count) {
this.pet = pet;
this.count = count;
}
public Pet getPet() {
return this.pet;
}
public long getCount() {
return this.count;
}
public String getEnterPetType() {
return this.pet.getPetType();
}
}
public static class DogCatQueue {
//dog队列
private Queue<PetEnterQueue> dogQ;
//cat队列
private Queue<PetEnterQueue> catQ;
//计数器
private long count;
//构造函数,初始化一个catQ和dogQ 并设置计数器为0
public DogCatQueue() {
this.dogQ = new LinkedList<PetEnterQueue>();
this.catQ = new LinkedList<PetEnterQueue>();
this.count = 0;
}
/**
* 队列中添加元素,根据类型来判断进入那个队列
* @param pet
*/
public void add(Pet pet) {
if (pet.getPetType().equals("dog")) {
this.dogQ.add(new PetEnterQueue(pet, this.count++));
} else if (pet.getPetType().equals("cat")) {
this.catQ.add(new PetEnterQueue(pet, this.count++));
} else {
throw new RuntimeException("err, not dog or cat");
}
}
/**
* 按进队的顺序弹出一个元素 两个队列都不为空的时候,比较队头哪个小弹出哪个
* @return
*/
public Pet pollAll() {
if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) {
//peek()获取元素 不弹出
if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) {
//dog的计数小弹dog
return this.dogQ.poll().getPet();
} else {
//cat的计数小弹cat
return this.catQ.poll().getPet();
}
//dog不为空,弹出dog
} else if (!this.dogQ.isEmpty()) {
return this.dogQ.poll().getPet();
//cat不为空,弹出cat
} else if (!this.catQ.isEmpty()) {
return this.catQ.poll().getPet();
} else {
throw new RuntimeException("err, queue is empty!");
}
}
/**
* @Desc dog不为空,则弹出dog
* @return
*/
public Dog pollDog() {
if (!this.isDogQueueEmpty()) {
return (Dog) this.dogQ.poll().getPet();
} else {
throw new RuntimeException("Dog queue is empty!");
}
}
/**
* @Desc cat不为空,则弹出cat
* @return
*/
public Cat pollCat() {
if (!this.isCatQueueEmpty()) {
return (Cat) this.catQ.poll().getPet();
} else
throw new RuntimeException("Cat queue is empty!");
}
public boolean isEmpty() {
return this.dogQ.isEmpty() && this.catQ.isEmpty();
}
public boolean isDogQueueEmpty() {
return this.dogQ.isEmpty();
}
public boolean isCatQueueEmpty() {
return this.catQ.isEmpty();
}
}
public static void main(String[] args) {
DogCatQueue test = new DogCatQueue();
Pet dog1 = new Dog();
Pet cat1 = new Cat();
Pet dog2 = new Dog();
Pet cat2 = new Cat();
Pet dog3 = new Dog();
Pet cat3 = new Cat();
test.add(dog1);
test.add(cat1);
test.add(dog2);
test.add(cat2);
test.add(dog3);
test.add(cat3);
test.add(dog1);
test.add(cat1);
test.add(dog2);
test.add(cat2);
test.add(dog3);
test.add(cat3);
test.add(dog1);
test.add(cat1);
test.add(dog2);
test.add(cat2);
test.add(dog3);
test.add(cat3);
while (!test.isDogQueueEmpty()) {
System.out.println(test.pollDog().getPetType());
}
while (!test.isEmpty()) {
System.out.println(test.pollAll().getPetType());
}
}
}