Tang Laoshi C# advanced course exercises (self-written, if there is a better method, welcome to discuss) (1)

Tang Laoshi C# advanced course exercises (self-written, if there is a better method, welcome to discuss)

Table of contents

Lesson 4 Stack Stack:

1. Briefly describe the storage rules of the stack: first in, last out

2. Write a method to calculate the binary number of any number, store it in a stack structure, and then print it out.

 private static void ToBinarySystem(int num)
        {
    
    
            Stack stack = new Stack();
            for (;num >= 1;)
            {
    
    
                stack.Push(num % 2);
                num = num / 2;
            }
            foreach (var item in stack)
            {
    
    
                Console.Write(item);
            }         
        }

Lesson 6 Queue Queue

1. Briefly describe the storage rules of the queue: first in, first out

2. Use a queue to store messages, store 10 messages at a time, and print a message every once in a while. There must be an obvious sense of pause when the console prints messages (the sense of pause has not yet been achieved)

static void PrintQueue()
        {
    
    
            Queue queue = new Queue();
            for (int i = 0; i < 10; i++)
            {
    
    
                queue.Enqueue(i);
            }

            foreach (var item in queue)
            {
    
    
                Console.WriteLine(item);
            }
        }

The following is the artificial intelligence ghostwriting effect for reference:

using System;
using System.Collections.Generic;
using System.Threading;

public class MessageQueue
{
    
    
    private Queue<string> queue;
    private int maxCount;
    private int printInterval;

    public MessageQueue(int maxCount, int printInterval)
    {
    
    
        this.queue = new Queue<string>();
        this.maxCount = maxCount;
        this.printInterval = printInterval;
    }

    public void Enqueue(string message)
    {
    
    
        lock (queue)
        {
    
    
            queue.Enqueue(message);
            if (queue.Count == maxCount)
            {
    
    
                PrintMessages();
            }
        }
    }

    private void PrintMessages()
    {
    
    
        Console.WriteLine("Printing messages...");
        while (queue.Count > 0)
        {
    
    
            Thread.Sleep(printInterval);
            Console.WriteLine(queue.Dequeue());
        }
    }
}

public class Program
{
    
    
    public static void Main()
    {
    
    
        MessageQueue messageQueue = new MessageQueue(10, 1000);
        for (int i = 0; i < 10; i++)
        {
    
    
            messageQueue.Enqueue($"Message {
      
      i + 1}");
        }
    }
}

Lesson 8 Hashtable table

1. Please describe the storage rules of Hashtable: storage through key-value pairs

2. Make a monster manager to provide methods for creating monsters and removing monsters. Each monster has its own unique ID

Monster manager class:

    /// <summary>
    /// 怪物管理器,提供创建怪物,移除怪物的方法。每个怪物都有自己的唯一ID
    /// </summary>
    class MonsterManager
    {
    
    
        //创建怪物的哈希表
        Hashtable monsterHashtable = new Hashtable();
        
        /// <summary>
        /// 创建怪物
        /// </summary>
        /// <param name="id">怪物的ID</param>
        /// <param name="name">怪物的名字</param>
        public void CreateMonster(int id,string name)
        {
    
    
            //判断现有的怪物哈希表里面存不存在要加入的怪物
            if (!monsterHashtable.Contains(id))
            {
    
    
                //不存在,在哈希表里面加入怪物
                monsterHashtable.Add(id, name);
            }
            else
            {
    
    
                //存在,给用户一个输出提示
                Console.WriteLine("已存在此怪物ID");
            }
        }

        /// <summary>
        /// 通过ID移除怪物
        /// </summary>
        /// <param name="id">怪物ID</param>
        public void RemoveMonster(int id)
        {
    
    
            //判断存不存在要删除的怪物
            if (monsterHashtable.Contains(id))
            {
    
    
                //存在,删除怪物
                monsterHashtable.Remove(id);
            }
            else
            {
    
    
                Console.WriteLine("不存在此怪物");
            }
        }

        /// <summary>
        /// 便利当前哈希表中的所有怪物
        /// </summary>
        public void ShowMonster()
        {
    
    
            foreach (var item in monsterHashtable.Keys)
            {
    
    
                Console.WriteLine("怪物ID:"+item+"\t 怪物名字:"+monsterHashtable[item]);
            }
        }
    }

Main function call:

static void Main(string[] args)
        {
    
    
            MonsterManager monsterMgr = new MonsterManager();
            monsterMgr.CreateMonster(1, "1号怪物");
            monsterMgr.CreateMonster(2, "2号怪物");
            monsterMgr.CreateMonster(3, "3号怪物");
            monsterMgr.ShowMonster();
            Console.WriteLine("********进行删除操作**********");
            monsterMgr.RemoveMonster(2);
            monsterMgr.ShowMonster();
            Console.ReadKey();
        }

operation result

怪物ID:3        怪物名字:3号怪物
怪物ID:2        怪物名字:2号怪物
怪物ID:1        怪物名字:1号怪物
********进行删除操作**********
怪物ID:3        怪物名字:3号怪物
怪物ID:1        怪物名字:1号怪物

Lesson 10 Generic Knowledge Points

1. Define a generic method to determine the type

Define a generic method that determines the type of the type and returns the name of the type and the number of bytes it occupies. If it is an int, it returns "integer, 4 bytes". Only the following types are considered: int: integer
char
:
character
float : Single-precision floating-point number
string: String
If it is other types, return "other types"
(type judgment can be made by typeof(type) == typeof(type))

private static string JudgmentType<T>()
        {
    
    
           
            if (typeof(T) == typeof(int))
            {
    
    
                return "整形" + "\t" + sizeof(int)+"字节";
            }
            else if(typeof(T) == typeof(char))
            {
    
    
                return "字符" + "\t" + sizeof(char) + "字节";
            }
            else if (typeof(T) == typeof(float))
            {
    
    
                return "单精度浮点数" + "\t" + sizeof(float) + "字节";
            }
            else if (typeof(T) == typeof(string))
            {
    
    
                return "字符串" + "\t" + "没有预定字节";
            }
            else
            {
    
    
                return "其他类型";
            }           
        }

Lesson 12 Generic Constraints

1. Use generics to implement a singleton pattern base class

The code provided here is the singleton pattern base class used in unity

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 定义一个基类,用于实现单例模式
public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    
    
    // 加锁的对象,用于线程安全
    private static readonly object _lock = new object();
    // 静态变量,用于存储单例实例
    private static T _instance = null;

    // 静态属性,用于获取单例实例
    public static T Instance
    {
    
    
        get {
    
    
            // 加锁,保证在多线程环境中只有一个实例被创建
            lock (_lock) {
    
    
                if (_instance == null)
                    _instance = FindObjectOfType<T>(); // 查找场景中是否已经存在该类型的对象
                return _instance;
            }
        }
    }

    // 在 Awake() 中进行初始化,并处理多实例的情况
    protected virtual void Awake()
    {
    
    
        // 加锁,保证在多线程环境中只有一个实例被创建
        lock (_lock) {
    
    
            // 第一次创建实例时,将自己设置为单例实例,不销毁该对象
            if (_instance == null) {
    
    
                _instance = (T)this;
                DontDestroyOnLoad(gameObject); // 如果需要跨场景使用单例,使用 DontDestroyOnLoad 保持对象不被销毁
            } 
            // 如果不同的实例被创建,销毁新的实例,保证单例的唯一性
            else if (_instance != this) {
    
    
                Destroy(gameObject);
            }
        }
    }

    // 如果该实例被销毁,将实例设置为空
    protected virtual void OnDestroy()
    {
    
    
        if (_instance == this) {
    
    
            _instance = null;
        }
    }
}

2. Use generic knowledge points to imitate ArrayList to implement a class of uncertain array type to implement the add, delete, check and modify method.

class ArrayList<T>
    {
    
    
        private T[] items;
        public ArrayList()
        {
    
    
            items = new T[0];
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="value"></param>
        public void Add(T value)
        {
    
    
            T[] newItems = new T[items.Length + 1];
            for (int i = 0; i < items.Length; i++)
            {
    
    
                newItems[i] = items[i];
            }
            newItems[newItems.Length - 1] = value;
            items = newItems;

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="index"></param>
        public void RemoveAt(int index)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            T[] newItems = new T[items.Length - 1];
            for (int i = 0, j = 0; i < items.Length; i++)
            {
    
    
                if (i != index)
                {
    
    
                    newItems[j] = items[i];
                    j++;
                }
            }
            items = newItems;
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public T Get(int index)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            return items[index];
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public void Set(int index, T value)
        {
    
    
            if (index < 0 || index >= items.Length)
            {
    
    
                throw new IndexOutOfRangeException();
            }

            items[index] = value;
        }

        public int Count()
        {
    
    
            return items.Length;
        }
    }

Main function call:

 static void Main(string[] args)
        {
    
    
            ArrayList<int> intArray = new ArrayList<int>();
            intArray.Add(1);
            intArray.Add(2);
            intArray.Add(3);
            intArray.RemoveAt(1);
            intArray.Set(1, 4);
            Console.WriteLine(intArray.Get(0)); // 输出 1
            Console.WriteLine(intArray.Get(1)); // 输出 4
            Console.WriteLine(intArray.Count()); // 输出 2

            ArrayList<string> stringArray = new ArrayList<string>();
            stringArray.Add("apple");
            stringArray.Add("banana");
            stringArray.Add("orange");
            stringArray.RemoveAt(2);
            stringArray.Set(0, "pear");
            Console.WriteLine(stringArray.Get(0)); // 输出 pear
            Console.WriteLine(stringArray.Get(1)); // 输出 banana
            Console.WriteLine(stringArray.Count()); // 输出 2

            Console.ReadKey();
        }

Lesson 14 List Knowledge Points

1. Please describe the difference between List and ArrayList

1.List supports generics, and ArrayList does not support generics.
2.List does not have boxing and unboxing operations, while ArrayList has boxing and unboxing operations.

2. Create an integer List, add 10~1 to it, delete the fifth element in the List, traverse the remaining elements and print

			List<int> list = new List<int>();
            for (int i = 10; i > 0; i--)
            {
    
    
                list.Add(i);
            }
            list.RemoveAt(4);
            foreach (var item in list)
            {
    
    
                Console.Write(item+"\t");
            }

3. A Monster base class, from which the Boss and Gablin classes inherit. In the constructor of the monster class, storing it in a monster List and traversing the list can allow Boss and Gablin objects to produce different attacks.

 class Monster
     {
    
    
        public static List<Monster> monsters = new List<Monster>();
        public Monster()
        {
    
    
            monsters.Add(this);
        }
        public virtual void Attack()
        {
    
    
            Console.WriteLine("MonsterAtt");
        }
     }

    class Boss : Monster
    {
    
    
        public override void Attack()
        {
    
    
            Console.WriteLine("BossAtt");
        }
    }
    class Goblin : Monster
    {
    
    
        public override void Attack()
        {
    
    
            Console.WriteLine("GoblinAtt");
        }
    }

Main function call:

 Boss boss = new Boss();
            Goblin goblin = new Goblin();
            foreach (var item in Monster.monsters)
            {
    
    
                item.Attack();
            }

Lesson 16 Dictionary Knowledge Points

1. Use a dictionary to store the uppercase text corresponding to numbers from 0 to 9. Prompt the user to enter a number of no more than three digits. Provide a method to return the uppercase number. For example: 306, return three zero.

			Console.WriteLine("请输入一个不超过3位的数");
            Console.WriteLine(GetInfo(int.Parse(Console.ReadLine())));
            
            string GetInfo(int num)
            {
    
    
                Dictionary<int, string> dic = new Dictionary<int, string>();
                dic.Add(0, "零");
                dic.Add(1, "壹");
                dic.Add(2, "贰");
                dic.Add(3, "叁");
                dic.Add(4, "肆");
                dic.Add(5, "伍");
                dic.Add(6, "陆");
                dic.Add(7, "柒");
                dic.Add(8, "捌");
                dic.Add(9, "玖");

                string str = "";
                //得百位
                int b = num / 100;
                if (b != 0)
                {
    
    
                    str += dic[b];
                }
                //得十位数
                int s = num % 100 / 10;
                if (s != 0 || str != "")
                {
    
    
                    str += dic[s];
                }
                //得个位
                int g = num % 10;
                str += dic[g];

                return str;
            }

2. Calculate the number of times each letter appears "Welcome to Unity World!", use a dictionary to store it, and finally traverse the entire dictionary, case-insensitively

 string str = "Welcome to Unity World!";
            Dictionary<char, int> strDic = new Dictionary<char, int>();
            for (int i = 0; i < str.Length; i++)
            {
    
    
                if (strDic.ContainsKey(str[i]))
                {
    
    
                    strDic[str[i]]+=1;
                }
                else
                {
    
    
                    strDic.Add(str[i], 1);
                }
            }

            foreach (var item in strDic.Keys)
            {
    
    
                Console.WriteLine("字母{0}出现了{1}次",item,strDic[item]);
            }

Lesson 18 Sequential storage and chain storage knowledge points

1. Please tell me what are the commonly used data structures

Array, stack, queue, linked list, tree, graph, heap, hash table

2. Please describe the difference between sequential storage and chain storage

Sequential storage: A set of storage units with consecutive addresses is used to store a linear table in the memory (continuous address storage).
Chain storage: A set of arbitrary storage units are used to store a linear table in the memory (any address storage).

3. Please try to implement a doubly linked list yourself, and provide the following methods and attributes: the number of data, head node, tail node, adding data to the end of the linked list, and deleting the node at the specified position.

Linked list related code:

    /// <summary>
    /// 链表节点
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    class LinkedNode<T>
    {
    
    
        public T value;
        public LinkedNode<T> frontNode;//上一个链表节点
        public LinkedNode<T> nextNode;//下一个链表节点

        public LinkedNode(T value)
        {
    
    
            this.value = value;
        }      
    }   
    /// <summary>
    /// 链表
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    class LinkedList<T>
    {
    
    
        private int count = 0;
        private LinkedNode<T> head;
        private LinkedNode<T> last;
        public LinkedNode<T> Head {
    
     get {
    
     return head; } }
        public LinkedNode<T> Last {
    
     get {
    
     return last; } }
        public int Count {
    
     get {
    
     return count; } }

        public void Add(T value)
        {
    
    
            LinkedNode<T> node = new LinkedNode<T>(value);
            if (head == null)
            {
    
    
                head = node;
                last = node;
            }
            else
            {
    
    
                //添加一个数据,添加到尾部
                //让尾部的下一个节点等于要加入的节点
                last.nextNode = node;
                //要加入的节点的上一步节点等于尾部节点
                node.frontNode = last;
                //尾部节点替换为当前加入的节点
                last = node;
            }
            ++count;//添加了一个节点
        }

        public void RemoveAt(int index)
        {
    
    
            //不能越界
            if (index >= count || index < 0)
            {
    
    
                Console.WriteLine("只有{0}个节点,请输入合法位置", count);
                return;
            }
            int tempCount = 0;
            LinkedNode<T> tempNode = head;
            while (true)
            {
    
    
                //如果是要移除的节点,那么直接移除
                if (tempCount == index)
                {
    
                      
                    //如果是头节点,那么头节点就等于下一个节点
                    if (index==0)
                    {
    
    
                        head = head.nextNode;
                    }else if (index == count - 1)
                    {
    
    
                        //如果是尾节点,那么让尾节点的上一节点为尾节点
                        last = last.frontNode;
                    }

                    //如果是中部节点
                    if (tempNode.frontNode != null)
                    {
    
    
                        //如果上一个节点不为空。则让上一个节点的下一个节点等于自身的下一个节点
                        tempNode.frontNode.nextNode = tempNode.nextNode;
                    }
                    if (tempNode.nextNode != null)
                    {
    
    
                        //如果下一个节点不为空,则让下一个节点的上一个节点等于自身的上一个节点
                        tempNode.nextNode.frontNode = tempNode.frontNode;
                    }
                    //移除了一个元素,少一截
                    --count;
                    break;
                }

                //每次循环过后临时节点等于下一节点
                tempNode = tempNode.nextNode;
                ++tempCount;
            }

        }
    }

Main function call:

            LinkedList<int> link = new LinkedList<int>();
            link.Add(1);
            link.Add(2);
            link.Add(3);
            link.Add(4);
            LinkedNode<int> node=link.Head;
            while (node != null)
            {
    
    
                Console.WriteLine(node.value);
                node = node.nextNode;
            }
            Console.WriteLine("********************");
            link.RemoveAt(2);
            node = link.Head;
            while (node != null)
            {
    
    
                Console.WriteLine(node.value);
                node = node.nextNode;
            }

operation result:

1
2
3
4
********************
1
2
4

Lesson 20 LinkedList knowledge points

1. Use Linkedlist, add 10 random integer variables to it, traverse once in the forward direction to print out the information, and traverse in the reverse direction once to print out the information.

            LinkedList<int> linkedList = new LinkedList<int>();
            Random r = new Random();
            for (int i = 0; i < 10; i++)
            {
    
    
                linkedList.AddLast(r.Next(1, 101));
            }

            LinkedListNode<int> nowNode = linkedList.First;
            while (nowNode != null)
            {
    
    
                Console.WriteLine(nowNode.Value);
                nowNode = nowNode.Next;
            }

            Console.WriteLine("********************");
            nowNode = linkedList.Last;
            while (nowNode != null)
            {
    
    
                Console.WriteLine(nowNode.Value);
                nowNode = nowNode.Previous;
            }

Lesson 24 Delegated Knowledge Points

1. There is a family of three. The mother cooks, and the father, mother, and children all have to eat. Use delegation to simulate the process of cooking -> starting the meal -> eating.

    //一家三口,妈妈做饭,爸爸妈妈和孩子都要吃饭
    //用委托模拟做饭——>开饭——>吃饭的过程
    abstract class Person
    {
    
    
        public abstract void Eat();
    }

    class Mother : Person
    {
    
    
        public Action beginEat;

        public override void Eat()
        {
    
    
            Console.WriteLine("妈妈吃饭");
        }

        public void DoFood()
        {
    
    
            Console.WriteLine("妈妈做饭");

            Console.WriteLine("妈妈做饭做好了");

            //执行委托函数
            if(beginEat != null)
            {
    
    
                beginEat();
            }
        }
    }

    class Father:Person
    {
    
    
        public override void Eat()
        {
    
    
            Console.WriteLine("爸爸吃饭");
        }
    }

    class Son:Person
    {
    
    
        public override void Eat()
        {
    
    
            Console.WriteLine("孩子吃饭");
        }
    }
    class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Console.WriteLine("委托练习题");

            Mother m = new Mother();
            Father f = new Father();
            Son s = new Son();
            //告诉妈妈 一会做好了 我要吃
            m.beginEat += f.Eat;
            m.beginEat += s.Eat;
            m.beginEat += m.Eat;
            //做饭
            m.DoFood();
            }
        }

2. After the monster dies, the player needs to add 10 yuan, the interface needs to update the data, and the achievements need to accumulate the number of monster kills. Please use delegation to simulate and implement these functions. You only need to write the core logic to express the process. There is no need to write too complicated.

    //怪物死亡后,玩家要加10块钱,界面要更新数据
    //成就要累加怪物击杀数,请用委托来模拟实现这些功能
    //只用写核心逻辑表现这个过程,不用写的太复杂

    class Monster
    {
    
    
        //当怪物死亡时 把自己作为参数传出去 
        public Action<Monster> deadDoSomthing;
        //怪物成员变量 特征 价值多少钱
        public int money = 10;

        public void Dead()
        {
    
    
            Console.WriteLine("怪物死亡");
            if(deadDoSomthing != null)
            {
    
    
                deadDoSomthing(this);
            }
            //一般情况下 委托关联的函数 有加 就有减(或者直接清空)
            deadDoSomthing = null;
        }
    }

    class Player
    {
    
    
        private int myMoney = 0;

        public void MonsterDeadDoSomthing(Monster m)
        {
    
    
            myMoney += m.money;
            Console.WriteLine("现在有{0}元钱", myMoney);
        }
    }

    class Panel
    {
    
    
        private int nowShowMoney = 0;

        public void MonsterDeadDo(Monster m)
        {
    
    
            nowShowMoney += m.money;
            Console.WriteLine("当前面板显示{0}元钱", nowShowMoney);
        }
    }

    class CJ
    {
    
    
        private int nowKillMonsterNum = 0;

        public void MonsterDeadDo(Monster m)
        {
    
    
            nowKillMonsterNum += 1;
            Console.WriteLine("当前击杀了{0}怪物", nowKillMonsterNum);
        }
    }
        class Program
    {
    
    
        static void Main(string[] args)
        {
    
    
            Monster monster = new Monster();
            Player p = new Player();
            Panel panel = new Panel();
            CJ cj = new CJ();

            monster.deadDoSomthing += p.MonsterDeadDoSomthing;
            monster.deadDoSomthing += panel.MonsterDeadDo;
            monster.deadDoSomthing += cj.MonsterDeadDo;

            monster.Dead();
            monster.Dead();

            Monster monster2 = new Monster();
            monster2.deadDoSomthing += p.MonsterDeadDoSomthing;
            monster2.deadDoSomthing += panel.MonsterDeadDo;
            monster2.deadDoSomthing += cj.MonsterDeadDo;
            monster2.Dead();
        }
    }

Lesson 26 Event Knowledge Points

1. There is a water heater, which includes a heater, an alarm, and a display. We power on the water heater. When the water temperature exceeds 95 degrees, 1. The alarm will start to sound a voice to tell you whose temperature it is. 2. The display will also change the water temperature prompt to indicate that the water has boiled.

Not well written, just for reference

    /// <summary>
    /// 热水器
    /// </summary>
    class Calorifier
    {
    
    
        public static event Action<int> MyEvent;

        public void BeginPower()
        {
    
    
            Heater heater = new Heater();
            heater.BeginHeater();
        }
        public static void CallEvent(int temp)
        {
    
    
            MyEvent?.Invoke(temp);
        }
    }
    /// <summary>
    /// 加热器
    /// </summary>
    class Heater
    {
    
    
        int temp = 80;
        public void BeginHeater()
        {
    
    
            while (true)
            {
    
    
                if (temp < 95)
                {
    
    
                    temp++;
                    Console.WriteLine("加热!!!\t"+temp);
                }
                if (temp >= 95)
                {
    
    
                    //报警器会开始发出语音,告诉你谁的温度
                    Alarm alarm = new Alarm();
                    //显示器也会改变水温提示,提示水已经烧开了
                    Monitor monitor = new Monitor();
                    Calorifier.CallEvent(temp);
                    break;
                }
            }
        }
        
    }
    /// <summary>
    /// 报警器
    /// </summary>
    class Alarm
    {
    
    
        public Alarm()
        {
    
    
            Calorifier.MyEvent += AlarmBegin;
        }

        private void AlarmBegin(int temp)
        {
    
    
            Console.WriteLine("发出报警声!!!"+temp);
        }
    }
    /// <summary>
    /// 显示器
    /// </summary>
    class Monitor
    {
    
    
        public Monitor()
        {
    
    
            Calorifier.MyEvent += MonitorBegin;
        }

        private void MonitorBegin(int temp)
        {
    
    
            Console.WriteLine("当前温度:" + temp+"水开了,已停止加热");
        }
    }

Main function call:

            Calorifier calor = new Calorifier();
            calor.BeginPower();

operation result:

加热!!!      81
加热!!!      82
加热!!!      83
加热!!!      84
加热!!!      85
加热!!!      86
加热!!!      87
加热!!!      88
加热!!!      89
加热!!!      90
加热!!!      91
加热!!!      92
加热!!!      93
加热!!!      94
加热!!!      95
发出报警声!!!95
当前温度:95水开了,已停止加热

Guess you like

Origin blog.csdn.net/u012177821/article/details/130943016