#include <iostream>
#include <stdio.h>
#include <string>
#include <queue>
using namespace std;
/*
问题:有家动物收容所只收容狗与猫,并且严格遵守“先进先出”原则。在收养该收容所的动物时,收养人只能收养所有动物中
“最老”(根据进入收容所的时间长短)的动物,或者,可以挑选猫或狗(同时必须收养此类动物中“最老”的)。换言之,收养人不能
自由挑选想收养的对象。请创建适用于这个系统的数据结构,实现各种操作方法,比如enqueue,dequeueAny,dequeueDog和dequeueCat等。
允许使用Java内置的LinkedList数据结构。
分析:所谓的挑选猫或狗,就是直接提取出任何动物,但是必须收养最老的动物。一种暴力破解方法就是直接遍历,从头到尾遍历,直接去获取最老的
动物,或者是挑选某个指定位置的猫,并要找出最老的猫一起返回;或者挑选某个狗以及最老的狗。
如果采用队列,那么就是先进先出。
一种实现队列的方法就是:采用链表来实现,并且采用尾插法,遍历的时候从头部开始。
挑选其实就是所谓的删除。
书上解法:只维护一个队列,找猫或狗需要遍历整个队列,增加复杂度。
简单方法:猫和狗各创建一个队列,将两个队列放入包裹类AnimalQueue,存储时间戳作为入队时间。
当调用dequeueAny时,查看狗队列和猫队列的时间戳即可。
我之所以没想到,是因为我想用一个队列来做。像类似的猫狗不同对象队列,小于x大于x进行划分,最好都用两个队列或两个链表来做。
另外想错了一个地方,dequeueDog就只能获取最老的狗而不是某个狗+最老的狗
输入:
5(猫狗个数之和)
d(表示狗) c(表示猫) c d c
3(指令个数)
dequeueAny
dequeueCat
dequeueDog
输出:
d(该操作返回的动物名称) 0(动物序号)
c 1
d 3
关键:
1 猫和狗各创建一个队列,将两个队列放入包裹类AnimalQueue,存储时间戳作为入队时间。
当调用dequeueAny时,查看狗队列和猫队列的时间戳即可。
我之所以没想到,是因为我想用一个队列来做。像类似的猫狗不同对象队列,小于x大于x进行划分,最好都用两个队列或两个链表来做。
另外想错了一个地方,dequeueDog就只能获取最老的狗而不是某个狗+最老的狗
*/
class Animal
{
public:
Animal(string& name) : _name(name){}
void setName(string& name)
{
_name = name;
}
virtual string getName()
{
return _name;
}
void setOrder(int order)
{
_order = order;
}
bool isOlderThan (Animal& other)
{
return _order < other._order;
}
int getOrder()
{
return _order;
}
protected:
string _name;
int _order;//用于记录顺序,数值越小,比较的时候越应该弹出
};
class Dog : public Animal
{
public:
//构造函数需要直接对父类构造函数进行赋值
Dog(string& name) : Animal(name){}
string getName()
{
return _name;
}
};
class Cat : public Animal
{
public:
//构造函数需要直接对父类构造函数进行赋值
Cat(string& name) : Animal(name){}
string getName()
{
return _name;
}
};
class AnimalQueue : public queue<Animal>
{
public:
AnimalQueue()
{
order = 0;
}
void enqueue(Animal& animal)
{
string name = animal.getName();
if(name == "c")
{
//使用引用转换dynamic_cast<Cat&> (animal),注意转换必须加括号
Cat cat = dynamic_cast<Cat&> (animal);
cat.setOrder(order++);
queueCat.push(cat);
}
else if(name == "d")
{
Dog dog = dynamic_cast<Dog&> (animal);
dog.setOrder(order++);
queueDog.push(dog);
}
}
//弹出队列中最老的元素,注意每次弹入元素时,需要设置顺序
Animal dequeueAny()
{
if(queueDog.empty() && queueCat.empty())
{
Animal animal(string("animal"));
return animal;
}
else if(queueCat.empty())
{
Dog dog = queueDog.front();
queueDog.pop();
return dog;
}
else if(queueDog.empty())
{
Cat cat = queueCat.front();
queueCat.pop();
return cat;
}
else
{
//根据顺序来找到最老的元素
Dog dog = queueDog.front();
Cat cat = queueCat.front();
bool isOlder = dog.isOlderThan(cat);
if(isOlder)
{
queueDog.pop();
return dog;
}
else
{
queueCat.pop();
return cat;
}
}
}
Animal dequeDog()
{
if(queueDog.empty())
{
Dog dog(string("dog"));
return dog;
}
else
{
Dog dog = queueDog.front();
queueDog.pop();
return dog;
}
}
Animal dequeCat()
{
if(queueCat.empty())
{
Cat cat(string("cat"));
return cat;
}
else
{
Cat cat = queueCat.front();
queueCat.pop();
return cat;
}
}
private:
queue<Dog> queueDog;
queue<Cat> queueCat;
int order;
};
int main(int argc, char* argv[])
{
int n;
string animal;
int commandNum;
string command;
while(cin >> n)
{
AnimalQueue animalQueue;
for(int i = 0 ; i < n ; i++)
{
cin >> animal;
if(animal == "d")
{
Dog dog(animal);
animalQueue.enqueue(dog);
}
else if(animal == "c")
{
Cat cat(animal);
animalQueue.enqueue(cat);
}
}
//数据输入完成后下面进行操作
cin >> commandNum;
for(int j = 0 ; j < commandNum ; j++)
{
cin >> command;
if(command == "dequeueAny")
{
Animal animal = animalQueue.dequeueAny();
cout << animal.getName() << " "<< animal.getOrder() << endl;
}
else if(command == "dequeueDog")
{
Animal animal = animalQueue.dequeDog();
cout << animal.getName() << " "<< animal.getOrder() << endl;
}
else if(command == "dequeueCat")
{
Animal animal = animalQueue.dequeCat();
cout << animal.getName() << " "<< animal.getOrder() << endl;
}
}
}
getchar();
return 0;
}
程序员面试金典: 9.3栈与队列 3.7猫狗动物队列
最新推荐文章于 2021-04-29 16:53:25 发布