猫狗队列(c++)

猫狗队列(c++)


【说明】:

本文是左程云老师所著的《程序员面试代码指南》第一章中“猫狗队列”这一题目的C++复现。

本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。

感谢左程云老师的支持。

#include <iostream>
#include <string>
#include<queue>
#include<stdexcept>//标准异常库
using namespace std;
//猫狗队列
//在C++中,类是不能加权限修饰符的,只有类的成员或者继承的时候才能加。
//这里是public继承,意思是Pet中所有的访问权限在Dog中不变,如果是peivate继承,那么是说Pet中的所有成员变成Dog的私有成员。
//在子类的构造函数中调用父类的有参构造函数就是下面这么用Cat():Pet("Cat"){};

class Pet
{
private:
	string type;
public:
	Pet(string type)
	{
		this->type = type;
	}
	Pet() {}
	string getPetType()
	{
		return this->type;
	}
};
class Dog :public Pet
{
public :
	Dog():Pet("dog") {}
};
class Cat :public Pet
{
public:
	Cat() :Pet("cat") {}
};
/************************以上为题目给出原始接口***********************/
//使用一个带时间戳的Pet类区分猫狗的进入顺序
class PetTimeStamp
{
private:
	Pet mypet;
	long timestamp;
public:
	//构造函数后面加了:是初始化列表,初始化myPet为p
	PetTimeStamp(Pet p, long count) :mypet(p)
	{
		this->timestamp = count;
	}
	Pet getPet()
	{
		return mypet;
	}
	long getTimeStamp()
	{
		return timestamp;
	}
	string getPetType()
	{
		return mypet.getPetType();
	}
};
//猫狗队列类,这列面有两个队列,每个队列的元素是加了时间戳的Pet类
class CatDogQ
{
private:
	queue<PetTimeStamp> dogQ, catQ;
	long timestamp;
public:
	CatDogQ()
	{
		timestamp = 0;
	}
	void push(Pet pet);
	Pet popAll();
	Dog popDog();
	Cat popCat();
	bool isEmpty();
	bool DogisEmpty();
	bool CatisEmpty();
};

//猫狗入队,入队的同时打上时间戳
void CatDogQ::push(Pet pet)
{
	if (pet.getPetType() == "dog")
		dogQ.push(PetTimeStamp(pet, this->timestamp++));
	else if (pet.getPetType() == "cat")
		catQ.push(PetTimeStamp(pet, this->timestamp++));
	else
		throw runtime_error("err, not dog or cat!");
}
由于是两个队列,因此要按照时间戳弹出,区分三种情况 :1 猫狗都有、2只有猫、3只有狗、都没有
Pet CatDogQ::popAll()
{
	if (!dogQ.empty() && !catQ.empty())//如果二者都不为空,按照时间错大小依次弹出
	{
		if (dogQ.front().getTimeStamp() < catQ.front().getTimeStamp())
		{
			Pet tmp;
			tmp = dogQ.front().getPet();
			dogQ.pop();
			return tmp;
		}
		else
		{
			Pet tmp;
			tmp = catQ.front().getPet();
			catQ.pop();
			return tmp;
		}
	}
	else if (!dogQ.empty())
	{
		Pet tmp;
		tmp = dogQ.front().getPet();
		dogQ.pop();
		return tmp;
	}
	else if (!catQ.empty())
	{
		Pet tmp;
		tmp = catQ.front().getPet();
		catQ.pop();
		return tmp;
	}
	else
	{
		throw runtime_error("Error ,empty queue!");
	}
}
Dog CatDogQ::popDog()
{
	if (!DogisEmpty())
	{
		Pet temP = dogQ.front().getPet();
		Dog tmp;
		Pet *p = &tmp;
		*p = temP;
		dogQ.pop();
		return tmp;
	}
	else
		throw runtime_error("Error,empty dog queue!");
}
Cat CatDogQ::popCat()
{
	if (!CatisEmpty())
	{
		Pet temP = catQ.front().getPet();
		Cat tmp;
		Pet *p = &tmp;
		*p = temP;
		catQ.pop();
		return tmp;
	}
	else
		throw runtime_error("Error,empty cat queue!");
}
bool CatDogQ::isEmpty()
{
	return catQ.empty() && dogQ.empty();
}
bool CatDogQ::DogisEmpty()
{
	return dogQ.empty();
}
bool CatDogQ::CatisEmpty()
{
	return catQ.empty();
}


int main()
{
	CatDogQ cdq;
	if (cdq.isEmpty())
		cout << "All queue is empty!" << endl;
	cdq.push(Cat());
	if (!cdq.DogisEmpty())
		cout << "Dog queue is not empty!" << endl;
	if (!cdq.CatisEmpty())
		cout << "Cat queue is not empty!" << endl;
	for (int i = 0; i < 2; i++)
	{
		cdq.push(Dog());
		cdq.push(Cat());

	}
	cout << "popAll:" << cdq.popAll().getPetType() << endl;
	cout << "popDog:" << cdq.popDog().getPetType() << endl;
	cout << "popCat:" << cdq.popCat().getPetType() << endl;
	cout << "popAll:" << cdq.popAll().getPetType() << endl;
	cout << "popAll:" << cdq.popAll().getPetType() << endl;

	if (cdq.isEmpty())
		cout << "All queue is empty!" << endl;

	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值