"Coding Interview Guide" -- 猫狗队列

题目】  

 1 宠物、狗和猫的类如下:
 2 public class Pet
 3 {
 4     private String type;
 5  
 6     public Pet(String type)
 7     {
 8         this.type = type;
 9     }
10  
11     public String getPetType()
12     {
13         return this.type;
14     }
15 }
16  
17 public class Dog extends Pet
18 {
19     public Dog()
20     {
21         super("Dog");
22     }
23 }
24  
25 public class Cat extends Pet
26 {
27     public Cat()
28     {
29         super("cat");
30     }
31 }
32  
33 实现一种猫狗队列的结构,要求如下:
34 (1) 用户可以调用add方法将Cat类或Dog类的实例放入队列中;
35 (2) 用户可以调用pollAll方法,将队列中所有的实例按照进队列的先后顺序依次弹出;
36 (3) 用户可以调用pollDog方法,将队列中Dog类的实例按照进队列的先后顺序依次弹出;
37 (4) 用户可以调用pollCat方法,将队列中Cat类的实例按照进队列的先后顺序依次弹出;
38 (5) 用户可以调用isEmpty方法,检查队列中是否还有Dog或Cat的实例;
39 (6) 用户可以调用isDogQueueEmpty方法,检查队列中是否有Dog类的实例;
40 (7) 用户可以调用isCatQueueEmpty方法,检查队列中是否有Cat类的实例。
41              

分析

  队列是一种只允许在一端插入,在另一端删除且不可访问除了队头元素外的其它元素的数据结构,插入的一端称为队尾,删除的一端称为队头,具有“先进先出”的特性,即先进队的元素也先出队。

  猫狗队列的结构要求pollDog方法和pollCat方法可以分别将队列中的Dog类、Cat类实例按照进队的先后顺序依次弹出。如果将Dog类实例和Cat类实例放在一个队列中,则pollDog方法和pollCat方法无法实现,因为队列中的元素除了队头元素可以访问外,其它的元素是不可以访问的,所以队列中的元素只能依次弹出,而不能根据类型弹出,所以解决方法是把Cat类实例和Dog类实例分别放到两个不同的队列中。

  猫狗队列的结构要求pollAll方法将猫狗队列中的元素按照进队的先后顺序依次弹出,但是因为我们选择用两个不同的队列分别存放Cat类实例和Dog类实例,那么怎么知道两个队列中元素在猫狗队列中的先后关系呢?解决方法是对于进队的每个Cat类实例和Dog类实例都打上一个时间戳,用于跟踪实例进猫狗队列的先后顺序,因此需要将Cat类实例和Dog类实例包装到一个对象中,该对象不仅包括Dog类或Cat类实例,还包括各自的时间戳。

  import java.util.Queue;
  import java.util.LinkedList;  

1
public class PetEnterQueue // CatDogQueue中的元素类型 2 { 3 private Pet pet; //pet存储Cat或Dog类实例的引用 4 private int count; // Cat或Dog类实例对应的时间戳,用于记录进队的先后顺序 5 6 public PetEnterQueue(Pet pet, int count) 7 { 8 this.pet = pet; 9 this.count = count; 10 } 11 12 public Pet getPet() 13 { 14 return pet; 15 } 16 17 public int getCount() 18 { 19 return count; 20 } 21 22 public String getType() 23 { 24 return getPet().getPetType(); 25 } 26 } 27 28 public class CatDogQueue 29 { 30 private Queue<PetEnterQueue> dogQ; // dogQ存放Dog类实例 31 private Queue<PetEnterQueue> catQ; // catQ存放Cat类实例 32 private int count; // 用来产生各实例的时间戳 33 34 public CatDogQueue() 35 { 36 dogQ = new LinkedList<>(); 37 catQ = new LinkedList<>(); 38 count = 0; 39 } 40 41 public void add(Pet pet) 42 { 43 if(pet.getPetType().equals("Dog")) 44 { 45 dogQ.add(new PetEnterQueue(pet, count++)); 46 } 47 else if(pet.getPetType().equals("Cat")) 48 { 49 catQ.add(new PetEnterQueue(pet, count++)); 50 } 51 else 52 { 53 throw new RuntimeException("err, pet is not the instance of Cat or Dog class."); 54 } 55 } 56 57 public Pet pollAll() 58 { 59 if(!isDogQueueEmpty() && !isCatQueueEmpty()) 60 { 61 if(dogQ.peek().getCount() < catQ.peek().getCount()) 62 { 63 return pollDog(); 64 } 65 else 66 { 67 return pollCat(); 68 } 69 } 70 else if(!isDogQueueEmpty()) 71 { 72 return pollDog(); 73 } 74 else if(!isCatQueueEmpty()) 75 { 76 return pollCat(); 77 } 78 else 79 { 80 throw new RuntimeException("err, the CatDogQueue is empty."); 81 } 82 } 83 84 public Dog pollDog() 85 { 86 if(!isDogQueueEmpty()) 87 { 88 return (Dog)dogQ.poll().getPet(); 89 } 90 else 91 { 92 throw new RuntimeException("err, dog queue is empty."); 93 } 94 } 95 96 public Cat pollCat() 97 { 98 if(!isCatQueueEmpty()) 99 { 100 return (Cat)catQ.poll().getPet(); 101 } 102 else 103 { 104 throw new RuntimeException("err, cat queue is empty."); 105 } 106 } 107 108 public boolean isEmpty() 109 { 110 return dogQ.isEmpty() && catQ.isEmpty(); 111 } 112 113 public boolean isDogQueueEmpty() 114 { 115 return dogQ.isEmpty(); 116 } 117 118 public boolean isCatQueueEmpty() 119 { 120 return catQ.isEmpty(); 121 } 122 }

来源:左程云老师《程序员代码面试指南》

原文地址:https://www.cnblogs.com/OoycyoO/p/10874948.html