程序员面试金典: 9.3栈与队列 3.7猫狗动物队列

#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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值