【C#算法实现】猫狗队列

本文介绍了如何使用C#实现《程序员代码面试指南》中的猫狗队列,通过自定义PetEnterQueue类记录宠物类型和入队顺序,并在CatDogQueue类中设计算法实现添加、出队、判空等操作,保持队列的特性和逻辑清晰。
摘要由CSDN通过智能技术生成

前言

本文是【程序员代码面试指南(第二版)学习笔记】C#版算法实现系列之一,用C#实现了《程序员代码面试指南》(第二版)栈和队列中的猫狗队列


一、题目要求

宠物、猫、狗类的定义如下

public class Pet {
    private string type;
    public Pet(string type) {
        this.type = type;
    }

    public string GetPetType() {
        return type;
    }
}

public class Dog: Pet {
    public Dog(): base("dog") {}
}

public class Cat: Pet {
    public Cat(): base("cat") {}
}

要求实现以下功能
1、用户可以调用 Add 方法将 Cat 类或 Dog 类的实例放入队列中;
2、用户可以调用 PollAll 方法,将队列中所有的实例按照进队列的先后顺序依次弹出;
3、用户可以调用 PollDog 方法,将队列中 Dog 类的实例按照进队列的先后顺序依次弹出;
4、用户可以调用 PollCat 方法,将队列中 Cat 类的实例按照进队列的先后顺序依次弹出;
5、用户可以调用 IsEmpty 方法,检查队列中是否还有 Dog 或 Cat 的实例;
6、用户可以调用 IsDogEmpty 方法,检查队列中是否有 Dog 类的实例;
7、用户可以调用 IsCatEmpty 方法,检查队列中是否有 Cat 类的实例。
注:不可修改原有的宠物和猫狗类,且可能同一个实例入队多次

二、算法设计及代码实现

2.1 算法思想

概述:由于不可以修改题目给出的类,那么就需要另写一个类,在该宠物类中添加上加入队伍的时间计数器,其中计数器越小表示入队越早。入队时,需要每入队一个猫或狗就让计数器加一;出队时,单独的猫狗队列出队不需要特殊操作,整个队列出队就需要判断猫狗队首的计数器,弹出最小的。判空就看长度判断即可。
自定义宠物类:有宠物和计数器两个字段,提供读取这两个字段的方法/属性,提供初始化两个字段的构造函数以及获取该宠物的类型的方法。
猫狗队列类:猫狗队列分开初始化,并初始化一个初始值为0的计数器。
1、入队:判断入队元素类型,类型必须是猫狗,是其他则抛出异常(在入队时控制好类型,其他方法内就不用判断是否存在猫狗以外的类型了)。猫则入猫队,狗则入狗队。
2、狗队出队:弹出一个狗队元素。
3、猫队出队:弹出一个猫队元素。
4、总队出队:由于猫狗队列可能有一个为空,所以要先判断不为空,才可以比较两队首的计数器。如果一队为空,那么直接弹出另一队的元素;都不为空,弹出两队中计数器较小的元素。
5、判断狗队为空:狗队长度为0返回true,否则为false。
6、判断猫队为空:猫队长度为0返回true,否则为false。
7、判断总队为空:狗队为空且猫队为空返回true,否则为false。

2.2 代码实现

using System.Collections;

public class PetEnterQueue {
    private Pet pet;
    private long count;
    public Pet PetProperty {
        get => pet;
    }

    public long Count {
        get => count;
    }

    public PetEnterQueue(Pet pet, long count) {
        this.pet = pet;
        this.count = count;
    }

    public string GetPetType() {
        return pet.Type;
    }
}

public class CatDogQueue {
    private Queue<PetEnterQueue> dogQue = new();
    private Queue<PetEnterQueue> catQue = new();
    private long count = 0;
    // 入队
    public void Add(Pet pet) {
        if (pet.Type == "dog") {
            dogQue.Enqueue(new PetEnterQueue(pet, count++));
        }
        else if(pet.Type == "cat") {
            catQue.Enqueue(new PetEnterQueue(pet, count++));
        }
        else {
            throw new SystemException("入队类型应该为猫或狗!");
        }
    }

    // 狗队列出队
    public Dog? PollDog() {
        return dogQue.Dequeue().PetProperty as Dog;
    }

    // 猫队列出队
    public Cat? PollCat() {
        return catQue.Dequeue().PetProperty as Cat;
    }

    // 从猫狗总队列中弹出一个应该出队的
    public Pet? PollAll() {
        // 其中一队为空
        if (IsDogEmpty()) {
            return PollCat();
        }
        if (IsCatEmpty()) {
            return PollDog();
        }
        // 都不为空
        if (dogQue.Peek().Count < catQue.Peek().Count) {
            return PollDog();
        }
        else {
            return PollCat();
        }
    }

    // 判断狗队列是否为空
    public bool IsDogEmpty() {
        return dogQue.Count == 0? true: false;
    }

    // 判断猫队列是否为空
    public bool IsCatEmpty() {
        return catQue.Count == 0? true: false;
    }

    // 判断猫狗总队列是否为空
    public bool IsEmpty() {
        return IsDogEmpty() && IsCatEmpty();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值