猫狗队列还是挺经典的一道题,思路是对不同类型的对象进行“包裹”,包裹后成为相同的类进行统一处理,不借助编译器的话,手写代码还是很容易出错的,果然简单的题也不是看起来那么简单。
直接上代码:
#include <iostream>
#include <string>
#include <queue>
#include <stdexcept>
using namespace std;
class Animal
{
private:
int order;
string type;
public:
Animal() {}
Animal(string s) : type(s) {}
void setOrder(int d) { order = d; }
int getOrder() { return order; }
void setType(string t) { type = t;}
string getType() { return type; }
bool isOrderThan(Animal a) { return this->order < a.order; }
};
class Dog : public Animal
{
public:
Dog() : Animal("Dog") {}
Dog(Animal& a) : Dog() {}
};
class Cat : public Animal
{
public:
Cat() : Animal("Cat") {}
Cat(Animal& a) : Cat() {}
};
class AnimalQueue : public Animal
{
queue<Dog> dogs;
queue<Cat> cats;
int order = 0;
public:
void enqueue(Animal& a)
{
// 为a设置顺序,该顺序统计每个动物的整体入队顺序
a.setOrder(order);
++order;
if("Dog" == a.getType()) dogs.push(Dog(a));
else if("Cat" == a.getType()) cats.push(Cat(a));
}
void enqueue(Dog a)
{
a.setOrder(order);
++order;
dogs.push(a);
}
void enqueue(Cat a)
{
a.setOrder(order);
++order;
cats.push(a);
}
Dog dequeueDog()
{
if(dogs.empty()){ throw runtime_error("队列已空!"); }
Dog a = dogs.front();
dogs.pop();
return a;
}
Cat dequeueCat()
{
if(cats.empty()) { throw runtime_error("队列已空!"); }
Cat a = cats.front();
cats.pop();
return a;
}
Animal dequeueAny()
{
// 查看猫狗队列的首部,弹出旧的值
if(dogs.empty()){
return dequeueCat();
}
else if(cats.empty()){
return dequeueDog();
}
Dog dog = dogs.front();
Cat cat = cats.front();
if(dog.isOrderThan(cat))
{
return dequeueDog();
} else {
return dequeueCat();
}
}
};
ostream& operator << (ostream& output, Animal& animal)
{
output << animal.getType();
return output;
}
void Test1()
{
AnimalQueue aq;
Animal temp;
aq.enqueue(Dog());
aq.enqueue(Cat());
aq.enqueue(Cat());
for(int i = 0; i < 3; ++i)
{
temp = aq.dequeueAny();
cout << "This is a " << temp << endl;
}
}
int main()
{
Test1();
return 0;
}