zoukankan      html  css  js  c++  java
  • 猫狗队列

    【说明】:

      本文是左程云老师所著的《程序员面试代码指南》第一章中“猫狗队列”这一题目的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
    View Code

      实现一种猫狗队列的结构,要求如下:

    • 用户可以调用 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
    View Code

      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
    View Code

      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();
    }
    View Code

      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;
    }
    View Code

    【一点说明】

      1、子类对象可以直接给父类赋值

      2、父类对象不可以直接给子类对象赋值

      3、解决父类对象不可以直接给子类对象赋值的问题的小技巧:    

    class A
    {};
    class B:public A        //B继承于A
    {};
    
    A a;    
    B b;
    A *pa = &b;  //声明类型为A的指针pa,并将子类对象b的地址赋予pa
    *pa = a;    //实现了父类对子类的赋值
    View Code

    注:

      转载请注明出处;

      转载请注明源思路来自于左程云老师的《程序员代码面试指南》。

  • 相关阅读:
    17、静态链表
    16、约瑟夫问题
    15、循环链表
    9、插入排序
    14、企业链表
    13、单向链表
    12、顺序表的顺序存储结构
    11、归并排序
    10、快速排序
    原型模式
  • 原文地址:https://www.cnblogs.com/PrimeLife/p/5318291.html
Copyright © 2011-2022 走看看