【说明】:
本文是左程云老师所著的《程序员面试代码指南》第一章中“猫狗队列”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
宠物、狗和猫的类如下:
/* *文件名:pet.h *作者: *摘要:pet、cat、dog的原声明及实现 */ #ifndef _PET_H #define _PET_H #include <string> using namespace std; class Pet { public: Pet(string type) { this->type = type; } string getPetType() { return type; } private: string type; }; class Dog:public Pet { public: Dog():Pet("dog"){} }; class Cat:public Pet { public: Cat():Pet("cat"){} }; #endif
实现一种猫狗队列的结构,要求如下:
- 用户可以调用 push 的方法,将 cat 类或者 dog 类的实例放入队列中;
- 用户可以调用 popAll 的方法,将队列中所有的实例按照进队列的先后顺序依次弹出;
- 用户可以调用 popDog 的方法,将队列中的 dog 类实例按照进队列的先后顺序依次弹出;
- 用户可以调用 popCat 的方法,将队列中的 cat 类实例按照进队列的先后顺序依次弹出;
- 用户可以调用 isEmpty 的方法,检查队列中是否还有 dog 或者 cat 类的实例;
- 用户可以调用 isDogEmpty 的方法,检查队列中是否还有 dog 类的实例;
- 用户可以调用 isCatEmpty 的方法,检查队列中是否还有 cat 类的实例。
【思路】:
以时间戳的方法区分猫狗的进入顺序。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
1、带时间戳的宠物类声明及实现代码
/* *文件名:petstamp.h *作者: *摘要:为添加的pet创建时间戳 */ #ifndef _PETSTAMP_H #define _PETSTAMP_H #include "pet.h" class PetStamp { public: PetStamp(Pet p,long count) :pet(p) { this->count = count; } Pet getPet() { return pet; } long getCount() { return count; } string getPetType() { return pet.getPetType(); } private: Pet pet; long count; }; #endif
2、猫狗队列的声明代码
/* *文件名:CatDogQue.h *作者: *摘要:猫狗队列的声明 */ #ifndef _CATDOGQUE_H #define _CATDOGQUE_H #include "pet.h" #include "petstamp.h" #include <queue> using namespace std; class CatDogQue { public: CatDogQue(); void push(Pet pet); Pet popAll(); Dog popDog(); Cat popCat(); bool isEmpty(); bool isDogEmpty(); bool isCatEmpty(); private: queue<PetStamp> dogQ; queue<PetStamp> catQ; long count; }; #endif
3、猫狗队列的实现代码
/* *文件名:CatDogQue.cpp *作者: *摘要:猫狗队列的声明。 */ #include "CatDogQue.h" #include <stdexcept> using namespace std; CatDogQue::CatDogQue() { count = 0; } void CatDogQue::push(Pet pet) { if("dog" == pet.getPetType()) dogQ.push(PetStamp(pet,count++)); else if("cat" == pet.getPetType()) catQ.push(PetStamp(pet,count++)); else throw runtime_error("err,not dog or cat!"); return ; } Pet CatDogQue::popAll() { if(!catQ.empty() && !dogQ.empty()) { if(dogQ.front().getCount() < catQ.front().getCount()) { Pet tmp = dogQ.front().getPet(); dogQ.pop(); return tmp; } else { Pet tmp = catQ.front().getPet(); catQ.pop(); return tmp; } } else if (!catQ.empty()) { Pet tmp = catQ.front().getPet(); catQ.pop(); return tmp; } else if (!dogQ.empty()) { Pet tmp = dogQ.front().getPet(); dogQ.pop(); return tmp; } else { throw runtime_error("Error,empty queue!"); } } Dog CatDogQue::popDog() { if (!dogQ.empty()) { Pet tmpP = dogQ.front().getPet(); Dog tmpD; Pet *pd = &tmpD; *pd = tmpP; dogQ.pop(); return tmpD; } else { throw runtime_error("Error,empty dog queue!"); } } Cat CatDogQue::popCat() { if (!catQ.empty()) { Pet tmpP = catQ.front().getPet(); Cat tmpC; Pet *pc = &tmpC; *pc = tmpP; catQ.pop(); return tmpC; } else { throw runtime_error("Error,empty cat queue!"); } } bool CatDogQue::isEmpty() { return dogQ.empty() && catQ.empty(); } bool CatDogQue::isDogEmpty() { return dogQ.empty(); } bool CatDogQue::isCatEmpty() { return catQ.empty(); }
4、测试代码
/* *文件名:test.cpp *作者: *摘要:猫狗队列的测试代码 */ #include "CatDogQue.h" #include <iostream> using namespace std; int main() { CatDogQue cdq; if(cdq.isEmpty()) cout << "All queue is empty!" << endl; cdq.push(Dog()); if(!cdq.isDogEmpty()) cout << "Dog queue is not empty!" << endl; if(cdq.isCatEmpty()) cout << "Cat queue is Empty!" << endl; for(int i=0;i<2;i++) { cdq.push(Cat()); cdq.push(Dog()); } 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; }
【一点说明】
1、子类对象可以直接给父类赋值
2、父类对象不可以直接给子类对象赋值
3、解决父类对象不可以直接给子类对象赋值的问题的小技巧:
class A {}; class B:public A //B继承于A {}; A a; B b; A *pa = &b; //声明类型为A的指针pa,并将子类对象b的地址赋予pa *pa = a; //实现了父类对子类的赋值
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。
【说明】:
本文是左程云老师所著的《程序员面试代码指南》第一章中“猫狗队列”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
宠物、狗和猫的类如下:
/* *文件名:pet.h *作者: *摘要:pet、cat、dog的原声明及实现 */ #ifndef _PET_H #define _PET_H #include <string> using namespace std; class Pet { public: Pet(string type) { this->type = type; } string getPetType() { return type; } private: string type; }; class Dog:public Pet { public: Dog():Pet("dog"){} }; class Cat:public Pet { public: Cat():Pet("cat"){} }; #endif
实现一种猫狗队列的结构,要求如下:
- 用户可以调用 push 的方法,将 cat 类或者 dog 类的实例放入队列中;
- 用户可以调用 popAll 的方法,将队列中所有的实例按照进队列的先后顺序依次弹出;
- 用户可以调用 popDog 的方法,将队列中的 dog 类实例按照进队列的先后顺序依次弹出;
- 用户可以调用 popCat 的方法,将队列中的 cat 类实例按照进队列的先后顺序依次弹出;
- 用户可以调用 isEmpty 的方法,检查队列中是否还有 dog 或者 cat 类的实例;
- 用户可以调用 isDogEmpty 的方法,检查队列中是否还有 dog 类的实例;
- 用户可以调用 isCatEmpty 的方法,检查队列中是否还有 cat 类的实例。
【思路】:
以时间戳的方法区分猫狗的进入顺序。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现】:
1、带时间戳的宠物类声明及实现代码
/* *文件名:petstamp.h *作者: *摘要:为添加的pet创建时间戳 */ #ifndef _PETSTAMP_H #define _PETSTAMP_H #include "pet.h" class PetStamp { public: PetStamp(Pet p,long count) :pet(p) { this->count = count; } Pet getPet() { return pet; } long getCount() { return count; } string getPetType() { return pet.getPetType(); } private: Pet pet; long count; }; #endif
2、猫狗队列的声明代码
/* *文件名:CatDogQue.h *作者: *摘要:猫狗队列的声明 */ #ifndef _CATDOGQUE_H #define _CATDOGQUE_H #include "pet.h" #include "petstamp.h" #include <queue> using namespace std; class CatDogQue { public: CatDogQue(); void push(Pet pet); Pet popAll(); Dog popDog(); Cat popCat(); bool isEmpty(); bool isDogEmpty(); bool isCatEmpty(); private: queue<PetStamp> dogQ; queue<PetStamp> catQ; long count; }; #endif
3、猫狗队列的实现代码
/* *文件名:CatDogQue.cpp *作者: *摘要:猫狗队列的声明。 */ #include "CatDogQue.h" #include <stdexcept> using namespace std; CatDogQue::CatDogQue() { count = 0; } void CatDogQue::push(Pet pet) { if("dog" == pet.getPetType()) dogQ.push(PetStamp(pet,count++)); else if("cat" == pet.getPetType()) catQ.push(PetStamp(pet,count++)); else throw runtime_error("err,not dog or cat!"); return ; } Pet CatDogQue::popAll() { if(!catQ.empty() && !dogQ.empty()) { if(dogQ.front().getCount() < catQ.front().getCount()) { Pet tmp = dogQ.front().getPet(); dogQ.pop(); return tmp; } else { Pet tmp = catQ.front().getPet(); catQ.pop(); return tmp; } } else if (!catQ.empty()) { Pet tmp = catQ.front().getPet(); catQ.pop(); return tmp; } else if (!dogQ.empty()) { Pet tmp = dogQ.front().getPet(); dogQ.pop(); return tmp; } else { throw runtime_error("Error,empty queue!"); } } Dog CatDogQue::popDog() { if (!dogQ.empty()) { Pet tmpP = dogQ.front().getPet(); Dog tmpD; Pet *pd = &tmpD; *pd = tmpP; dogQ.pop(); return tmpD; } else { throw runtime_error("Error,empty dog queue!"); } } Cat CatDogQue::popCat() { if (!catQ.empty()) { Pet tmpP = catQ.front().getPet(); Cat tmpC; Pet *pc = &tmpC; *pc = tmpP; catQ.pop(); return tmpC; } else { throw runtime_error("Error,empty cat queue!"); } } bool CatDogQue::isEmpty() { return dogQ.empty() && catQ.empty(); } bool CatDogQue::isDogEmpty() { return dogQ.empty(); } bool CatDogQue::isCatEmpty() { return catQ.empty(); }
4、测试代码
/* *文件名:test.cpp *作者: *摘要:猫狗队列的测试代码 */ #include "CatDogQue.h" #include <iostream> using namespace std; int main() { CatDogQue cdq; if(cdq.isEmpty()) cout << "All queue is empty!" << endl; cdq.push(Dog()); if(!cdq.isDogEmpty()) cout << "Dog queue is not empty!" << endl; if(cdq.isCatEmpty()) cout << "Cat queue is Empty!" << endl; for(int i=0;i<2;i++) { cdq.push(Cat()); cdq.push(Dog()); } 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; }
【一点说明】
1、子类对象可以直接给父类赋值
2、父类对象不可以直接给子类对象赋值
3、解决父类对象不可以直接给子类对象赋值的问题的小技巧:
class A {}; class B:public A //B继承于A {}; A a; B b; A *pa = &b; //声明类型为A的指针pa,并将子类对象b的地址赋予pa *pa = a; //实现了父类对子类的赋值
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。
来源:https://www.cnblogs.com/PrimeLife/p/5318291.html