• 猫狗队列


    【说明】:

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

    注:

      转载请注明出处;

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

  • 相关阅读:
    第二次作业循环语句
    c语言01次作业分支,顺序结构
    PAT 1027. Colors in Mars
    PAT 1026 Table Tennis
    PAT 1035 Password
    PAT 1038. Recover the Smallest Number
    PAT 1028 List Sorting (25)
    PAT 1041 Be Unique (20)
    PAT 1025 PAT Ranking
    1037. Magic Coupon
  • 原文地址:https://www.cnblogs.com/PrimeLife/p/5318291.html
Copyright © 2020-2023  润新知