【左程云Java算法】Chapter1-4:猫狗队列

【左程云Java算法】Chapter1-4:猫狗队列
【题目】
宠物、狗和猫的类如下:

class Pet{
    private String type;
    private String name;
    public Pet(String type, String name){
        this.type = type;
        this.name = name;
    }

    public String getPetType(){
        return this.type;
    }

    public void printName(){
        System.out.println(this.name);
    }
}

【要求】
实现一种狗猫队列的结构,要求如下:
用户可以调用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类改写,加一个计数项来表示某一个实例进队列的时间。错误原因:不能擅自改变用户的类结构。
本题实现将不同的实例盖上时间戳的方法,但是又不能改变用户本身的类,所以定义一个新的类,具体实现请参看如下的PetEnterQueue类。

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类时,pet是用户原有的实例,count就是这个实例的时间戳。
我们实现的队列其实是PetEnterQueue类的实例。大体说来,首先有一个不断累加的数据项,用来表示实例进队列的时间;同时有两个队列,一个是只放dog类实例的队列dogQ,另一个是只放cat类实例的队列catQ。
在加入实例时,如果实例是dog,就盖上时间戳,生成对应的PetEnterQueue类的实例,然后放入dogQ;如果实例是cat,就盖上时间戳,生成对应的PetEnterQueue类的实例,然后放入catQ。具体过程请参看如下DogCatQueue类的add方法。
只想弹出dog类的实例时,从dogQ里不断弹出即可,具体过程请参看如下 DogCatQueue类的pollDog方法。
只想弹出cat类的实例时,从catQ里不断弹出即可,具体过程请参看如下 DogCatQueue类的pollCat方法。
想按实际顺序弹出实例时,因为dogQ的队列头表示所有dog实例中最早进队列的实例,同时catQ的队列头表示所有的cat实例中最早进队列的实例。则比较这两个队列头的时间戳,谁更早, 就弹出 谁。具体过程请参看如下 DogCatQueue类的pollAll方法。
DogCatQueue类的整体代码如下:

class DogCatQueue{
    private Queue<PetEnterQueue> dogQueue;
    private Queue<PetEnterQueue> catQueue;
    private long count;

    public DogCatQueue(){
        this.dogQueue = new LinkedList<PetEnterQueue>();
        this.catQueue = new LinkedList<PetEnterQueue>();
        this.count = 0;
    }

    public void add(Pet pet){
        if(pet.getPetType().equals("dog")){
            this.dogQueue.add(new PetEnterQueue(pet, this.count++));
        } else if (pet.getPetType().equals("cat")) {
            this.catQueue.add(new PetEnterQueue(pet, this.count++));
        }else{
            throw new RuntimeException("err, not dog or cat");
        }
    }

    public Pet pollAll(){
        if(!this.dogQueue.isEmpty() && !this.catQueue.isEmpty()){
            if(this.dogQueue.peek().getCount() < this.catQueue.peek().getCount()){
                return this.dogQueue.poll().getPet();
            }else{
                return this.catQueue.poll().getPet();
            }
        } else if (!this.dogQueue.isEmpty()) {
            return this.dogQueue.poll().getPet();
        } else if (this.catQueue.isEmpty()) {
            return this.catQueue.poll().getPet();
        }else{
            throw new RuntimeException("err, queue is empty!");
        }
    }

    public Dog pollDog(){
        if(!this.isDogQueueEmpty()){
            return (Dog) this.dogQueue.poll().getPet();
        }else{
            throw new RuntimeException("Dog queue is empty!");
        }
    }

    public Cat pollCat(){
        if(!this.isCatQueueEmpty()){
            return (Cat) this.catQueue.poll().getPet();
        }else{
            throw new RuntimeException("Cat queue is empty!");
        }
    }

    public boolean isEmpty(){
        return this.dogQueue.isEmpty() && this.catQueue.isEmpty();
    }

    public boolean isDogQueueEmpty(){
        return this.dogQueue.isEmpty();
    }

    public boolean isCatQueueEmpty(){
        return this.catQueue.isEmpty();
    }
}

开源地址

开源地址:https://github.com/hankangwen/AlgorithmByJava
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kerven_HKW

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值