算法题-栈和队列-04-猫狗队列

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类的实例;

解答:

本题考察实现特殊数据结构能力,以及针对特殊功能的算法设计能力。

  •  cat队列只放cat实例,dog队列只放dog实例,再用一个总队列放所有的实例。错误原因:cat、dog以及总队列的更新问题。
  •  用哈希表,key表示一个cat实例或dog实例,value表示这个实例进队列的次序。错误原因:不能支持一个实例多次进队列的功能需求,因为哈希表的key只能对应一个value值。
  •  将用户原有的cat或dog类改写,加一个计数项来表示某一个实例进队列的时间。错误原因:不能擅自改变用户的类结构。

本题实现将不同的实例盖上时间戳的方法,但是又不能改变用户本身的类,所以定义一个新的类,具体实现请参看如下:

public class PetEnterQueue{
    private Pet pet;
    private Long number;
    public PetEnterQueue(Pet pet,long count){
        this.pet=pet;
        this.number=number;
    }
    public Pet getPet() {
        return pet;
    }
    public Long getNumber() {
        return number;
    }
    public String getEnterPetType(){
        return this.pet.getPetType();
    }
}

在构造PetEnterQueue类时,pet是用户原有的实例,count就是这个实例的时间戳。

我们实现的队列其实是PetEnterQueue类的实例。答题来说,首先有一个不断累加的数据项,用来表示实例进队列的时间;同时有两个队列,一个是只放dog类的实例队列dogQ,另一个是只放cat类的实例队列catQ。

在加入实例时,如果实例是dog,就盖上时间戳,生产对应的PetEnterQueue类的实例,然后放入dogQ;反之如果是cat类的实例,也是如此。具体过程请看如下DogCatQueue类的add方法。

只想弹出dog类的实例时,从dogQ里不断弹出即可,具体过程参看如下的DogCatQueue类的pollDog方法。

反之只想弹出cat类的实例时,从catQ里不断弹出即可,具体过程请看如下DogCatQueue类的pollCat方法。

想按实际顺序弹出实例时,因为dogQ的队列头表示所有dog实例中的最早进入队列的实例,同时catQ的队列头表示cat实例找那个最早进队列的实例。则比较这两个队列头的时间戳,谁更早就弹出谁,具体请参看pollAll方法。

具体代码如下:

public class DogAndCatQueue {
    private Queue<PetEnterQueue> dogQ;
    private Queue<PetEnterQueue>catQ;
    private long count;
    public DogAndCatQueue(){
        this.catQ=new LinkedList<>();
        this.dogQ=new LinkedList<>();
        this.count=0;
    }
    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");
        }
    }
    public Pet pollAll(){
        if (!this.dogQ.isEmpty()&&!this.catQ.isEmpty()){
            if (this.dogQ.peek().getNumber()<this.catQ.peek().getNumber()){
                return this.dogQ.poll().getPet();
            }else {
                return this.catQ.poll().getPet();
            }
        }else if (!this.dogQ.isEmpty()){
            return this.dogQ.poll().getPet();
        }else if (!this.catQ.isEmpty()){
            return this.catQ.poll().getPet();
        }else {
            throw new RuntimeException("err,queue is empty!");
        }
    }
    public Dog pollDog(){
        if (!this.dogQ.isEmpty()){
            return (Dog)this.dogQ.poll().getPet();
        }else {
            throw new RuntimeException("Dog queue is empty!");
        }
    }
    public Cat pollCat(){
        if (!this.catQ.isEmpty()){
            return (Cat)this.catQ.poll().getPet();
        }else {
            throw new RuntimeException("Cat queue is empty!");
        }
    }
    public boolean isEmpty(){
        return this.catQ.isEmpty()&&this.dogQ.isEmpty();
    }
    public boolean isDogQueueEmpty(){
        return this.dogQ.isEmpty();
    }
    public boolean isCatQueueEmpty(){
        return this.catQ.isEmpty();
    }

    public static void main(String[] args) {
        DogAndCatQueue dogAndCatQueue = new DogAndCatQueue();
        Pet cat = new Pet("cat");
        Pet cat02 = new Pet("cat");
        Pet dog = new Pet("dog");
        Pet dog02 = new Pet("dog");
        Pet dog03 = new Pet("dog");
        dogAndCatQueue.add(cat);
        dogAndCatQueue.add(cat);
        dogAndCatQueue.add(cat02);
        dogAndCatQueue.add(dog);
        dogAndCatQueue.add(dog02);
        dogAndCatQueue.add(dog03);
    }
}

断点验证:

 

我们看到对应猫狗实例都是有编号的,说明有序,既然有序pollAll方法就实现了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值