C#编程训练

目录

练习1: 数组元素求和

练习2: 数组元素乘积

练习3: 数组元素平均值

练习4: 查找数组中的最大值

练习5: 查找数组中的偶数

练习6: 计算阶乘

练习7: 数组翻转

练习8: 字符串反转

练习9: 检查回文

练习10: 数组中的最大值和最小值

练习11: 素数检查器

练习12: 字符串中的最长无重复子串

练习13: 数字到字符串转换

练习14: 简单的日期格式化

练习15: 简单的计算器

练习16: 数组中的两数之和

练习17: 字符串去重

练习18: 滑动窗口最大值

练习19: 矩阵旋转

练习20: 字符串压缩

练习21: 有效的括号序列

练习22: 最长公共前缀



练习1: 数组元素求和

题目 : 编写一个C#程序,计算数组中所有元素的总和。
首先定义了一个名为 SumArray的方法,它接受一个整数数组作为参数,遍历数组中的每个元素并将它们累加起来,最后返回这个总和。
using System;
using System.Reflection.Metadata.Ecma335;
class ArraySum
{
    public static int SumArray(int[] arr)
    {
        int num = 0;
        foreach (int x in arr)
        {
            num += x;
        }
        return num;
    }

    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5 };
        Console.WriteLine(SumArray(numbers));
    }
}

运行结果:15


练习2: 数组元素乘积

题目 : 编写一个C#程序,计算数组中所有元素的乘积。
首先定义了一个名为 ProductArray方法遍历数组中的每个元素,将当前的乘积与数组中的每个元素相乘,从而累积得到整个数组的乘积。
using System;
class ArrayProduct
{
    public static long ProductArray(int[] arr)
    {
        long num = 1;
        foreach (int x in arr)
        {
            num *= x;
        }
        return num;
    }
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5 };
        Console.WriteLine(ProductArray(numbers));
    }
}

运行结果:120


练习3: 数组元素平均值

题目 : 编写一个C#程序,计算数组中所有元素的平均值。
定义了一个名为AverageArray的方法遍历数组中的每个元素,累加这些数值,最后将总和除以数组的长度来得到平均值。
using System;
class ArrayAverage
{
    public static double AverageArray(int[] arr)
    {
        double num = 0;
        foreach (int x in arr)
        {
            num += x;
        }
        double z =num / arr.Length;
        return z;
    }
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5 };
        Console.WriteLine(AverageArray(numbers));
    }
}

运行结果:3


练习4: 查找数组中的最大值

题目 : 编写一个C#程序,找到数组中的最大值。
定义了一个名为 MaxValue方法遍历数组中的每个元素,初始化时假设数组的第一个元素是最大值。通过比较,如果发现有比当前最大值更大的元素,就更新Max变量。
using System;
using System.Globalization;
class ArrayMax
{
    public static int MaxValue(int[] arr)
    {
        int Max = arr[0];
        for (int i = 0; i < arr.Length; i++)
        {
            if (arr[i] > Max)
            {
            Max = arr[i]; 
            }
        }
        return Max;
    }
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5 };
        Console.WriteLine(MaxValue(numbers));
    }
}

运行结果:5


练习5: 查找数组中的偶数

题目 : 编写一个C#程序,从数组中筛选出所有的偶数,并返回一个新的数组。
首先定义了一个 GetEvens方法,它遍历输入数组,检查每个元素是否为偶数,并将偶数添加到一个 List<int>中。完成遍历后,将列表转换为数组并返回。
using System;
using System.Collections.Generic;
using System.ComponentModel;
class EvenNumbers
{
    public static List<int> GetEvens(int[] arr)
    {
        List<int> num=new List<int>();
        foreach (int x in arr)
        {
            if (x % 2 == 0)
            {
                num.Add(x);
            }
        }
        return num;
    }
    static void Main(string[] args)
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6 };
        List<int> evenNumbers = GetEvens(numbers);
        foreach (int num in evenNumbers)
        {
            Console.Write(num + " ");
        }
    }
}

运行结果:2 4 6


练习6: 计算阶乘

题目 : 编写一个C#函数,计算给定非负整数的阶乘。
定义一个 CalculateFactorial函数接受一个整数参数 number,并返回其阶乘。函数内部首先检查输入是否为非负数,如果是负数则抛出 ArgumentException异常。接着,通过一个循环从1乘到 number,累乘的结果即为阶乘值。为了能够处理较大的阶乘结果,这里使用了 long类型来存储阶乘值。
using System;
class Factorial
{
    public static long CalculateFactorial(int number)
    {
      if (number < 0)
            {
                throw new ArgumentException("输入必须是非负整数");
            }
        long num = 1;
        for (int x = 1; x < number+1; x++)
        {
            num = x * num;
        }
        return num;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(CalculateFactorial(5));
    }
}

练习7: 数组翻转

题目 : 编写一个C#程序,将一个整数数组翻转。
定义一个 ReverseArray方法,它接收一个整数数组作为参数,并通过双指针技术原地翻转数组。
using System;
class ArrayReverse
{
    public static void ReverseArray(int[] arr)
    {
        int R=arr.Length;
        for(int i=0; i<arr.Length/2; i++)
        {
            int[]x = new int[R];
            x[i] = arr[i];
            arr[i] =arr[R-i-1];
            arr[R - i - 1] = x[i] ;
        }
    }
    static void Main(string[] args)
    {
        int[] array = { 1, 2, 3, 4, 5 };
        ReverseArray(array);
        foreach (int i in array)
        {
            Console.Write(i + " ");
        }
    }
}

运行结果:5 4 3 2 1


练习8: 字符串反转

题目 : 编写一个C#函数,反转一个字符串。
首先定义了一个 ReverseString函数接受一个字符串作为输入,然后利用 .ToCharArray()方法将其转换成字符数组。接着,调用 Array.Reverse()方法直接反转这个字符数组。最后,使用 new string(charArray)将修改后的字符数组转换回字符串。
using System;
class StringReversal
{
    public static string ReverseString(string s)
    {
        char[] charArray = s.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }
    static void Main(string[] args)
{
    Console.WriteLine(ReverseString("hello"));
}
}

运行结果:olleh


练习9: 检查回文

题目 : 编写一个C#函数,检查一个字符串是否是回文
定义一个 IsPalindrome函数首先将输入字符串然后,它使用两个指针分别从前向后和从后向前遍历字符串,比较对应位置的字符是否相同。如果在任何时候发现不匹配的字符,则立即返回 false。如果所有对应位置的字符都相等,则函数返回 true,表示该字符串是回文。
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
class PalindromeChecker
{
    public static bool IsPalindrome(string str)
    {
        int L = 0;
        int R = str.Length - 1;
        while (L <R)
        {
            while (L <R && !char.IsLetterOrDigit(str[L]))
            {
                L++;
            }
            while (L < R && !char.IsLetterOrDigit(str[R]))
            {
                R--;
            }
            if (char.ToLower(str[L]) != char.ToLower(str[R]))
            {
                return false; // 如果对应位置的字符不相等,则不是回文
            }
            L++;
            R--;
        }
        return true;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(IsPalindrome("racecar"));
    }
}

运行结果:True


练习10: 数组中的最大值和最小值

题目 : 编写一个C#函数,找出数组中的最大值和最小值。
定义了一个 FindMaxMin函数,它接收一个整数数组作为参数,并返回一个包含最大值和最小值的元组。函数内部首先检查数组是否为空,然后初始化 maxmin为数组的第一个元素。通过遍历数组,同时比较并更新这两个变量来找到最大值和最小值。
using System;
class MaxMinFinder
{
    public static Tuple<int, int> FindMaxMin(int[] arr)
    {
        if (arr == null || arr.Length == 0)
        {
            throw new ArgumentException("Array cannot be null or empty.");
        }
        int max = arr[0];
        int min = arr[0];
        foreach (int num in arr)
        {
            if (num > max)
            {
                max = num;
            }
            if(num < min)
            {
                min = num;
            }
        }
        return Tuple.Create(max, min);
    }
    static void Main(string[] args)
    {
        int[] array = { 3, 7, 1, 9, 2 };
        var result = FindMaxMin(array);
        Console.WriteLine($"Max: {result.Item1}, Min: {result.Item2}");
    }
}

运行结果:Max: 9, Min:1


练习11: 素数检查器

题目 : 编写一个C#函数,用于判断一个数字是否为素数。
定义一个 IsPrime函数首先处理了一些基本情况,如小于等于1的数不是素数,2和3是素数。然后,它排除了所有能被2或3整除的数。之后,通过一个优化过的循环,从5开始以步长6进行检查。
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System;
class PrimeChecker
{
    public static bool IsPrime(int number)
    {
        if (number<=1)
        { 
          return false;
        }
        if (number<=3)
        {
          return true;
        }
        if (number % 2 == 0 || number % 3 == 0)
        {
          return false;
        }
        int i = 5;
        while (i * i <= number)
        {
            if (number % i == 0 || number % (i + 2) == 0)
            {
                return false;
            }
            i += 6;
        }
        return true;
    }

        static void Main(string[] args)
        {
            Console.WriteLine(IsPrime(17));
        }
    }

运行结果:True


练习12: 字符串中的最长无重复子串

题目 : 找到一个字符串中的最长无重复字符的子串长度。
首先定义了一个方法 LengthOfLongestSubstring,它接收一个字符串 s作为输入。使用一个字典 charIndexMap来存储每个字符最后一次出现的位置。 leftright变量定义了当前无重复字符子串的左右边界。通过遍历字符串,不断更新窗口的左右边界和最大长度,最终返回最长无重复字符子串的长度。
using System.Linq;
using System;
class LongestUniqueSubstring
{
    public static int LengthOfLongestSubstring(string s)
    {
        Dictionary<char, int> charIndexMap = new Dictionary<char, int>();
        int left = 0, maxLength = 0;
        for (int right = 0; right < s.Length; right++)
        {
            if (charIndexMap.ContainsKey(s[right]))
            {
                left = Math.Max(left, charIndexMap[s[right]] + 1);
            }
            charIndexMap[s[right]] = right;
            maxLength = Math.Max(maxLength, right - left + 1);
        }
        return maxLength;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(LengthOfLongestSubstring("abcabcbb"));
    }
}

运行结果:3


练习13: 数字到字符串转换

题目 : 编写一个函数,将一个整数转换为其英文描述。
using System;
using System.Collections.Generic;

class NumberToWords {
    private static readonly Dictionary<int, string> OnesMap = new Dictionary<int, string> {
        {1, "One"}, {2, "Two"}, {3, "Three"}, {4, "Four"}, {5, "Five"},
        {6, "Six"}, {7, "Seven"}, {8, "Eight"}, {9, "Nine"}
    };
    private static readonly Dictionary<int, string> TeensMap = new Dictionary<int, string> {
        {10, "Ten"}, {11, "Eleven"}, {12, "Twelve"}, {13, "Thirteen"},
        {14, "Fourteen"}, {15, "Fifteen"}, {16, "Sixteen"}, {17, "Seventeen"},
        {18, "Eighteen"}, {19, "Nineteen"}
    };
    private static readonly Dictionary<int, string> TensMap = new Dictionary<int, string> {
        {2, "Twenty"}, {3, "Thirty"}, {4, "Forty"}, {5, "Fifty"},
        {6, "Sixty"}, {7, "Seventy"}, {8, "Eighty"}, {9, "Ninety"}
    };

    public static string ConvertNumberToWords(int number) {
        if (number < 1 || number > 999) {
            throw new ArgumentException("Number must be between 1 and 999");
        }

        if (number < 10) {
            return OnesMap[number];
        }
        if (number < 20) {
            return TeensMap[number];
        }
        if (number < 100) {
            int ten = number / 10;
            int one = number % 10;
            return TensMap[ten] + (one > 0 ? " " + OnesMap[one] : "");
        }
        // For numbers between 100 and 999
        int hundred = number / 100;
        int remainder = number % 100;
        string word = OnesMap[hundred] + " Hundred";
        if (remainder > 0) {
            word += " " + ConvertNumberToWords(remainder);
        }
        return word;
    }

    static void Main(string[] args) {
        Console.WriteLine(ConvertNumberToWords(15)); // 应输出 "Fifteen"
    }
}

运行结果:Fifteen


练习14: 简单的日期格式化

题目 : 编写一个函数,将当前日期格式化为“Day Month Year”形式。
定义一个 FormatDate函数首先获取当前的日期和时间(通过 DateTime.Now),然后使用 ToString方法将其格式化。
using System.Text;
using System;

class DateFormatter
{
    public static string FormatDate()
    {
        DateTime currentDate = DateTime.Now;
        string day = currentDate.Day.ToString();
        string month = currentDate.Month.ToString();
        string year = currentDate.Year.ToString();
        return $"{day}日 {month}月 {year}年";
    }
    static void Main(string[] args)
    {
        Console.WriteLine(FormatDate());
    }
}

运行结果:7日7月2024年


练习15: 简单的计算器

题目 : 编写一个简单的计算器函数,支持加、减、乘、除四种基本运算。
定义了一个 Calculate函数,它根据传入的运算符执行加、减、乘、除运算。在 Main方法中,程序从用户那里获取两个操作数和一个运算符,然后调用 Calculate函数计算结果,并处理可能的异常,比如输入的不是有效数字、除数为零,或输入了不支持的运算符。
using System;

class SimpleCalculator
{
    public static double Calculate(double num1, char op, double num2)
    {
        switch (op)
        {
            case '+':
                return num1 + num2;
            case '-':
                return num1 - num2;
            case '*':
                return num1 * num2;
            case '/':
                if (num2 != 0)
                    return num1 / num2;
                else
                    throw new DivideByZeroException("除数不能为0");
            default:
                throw new ArgumentException("运算符只有: +, -, *, /");
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine(Calculate(10, '+', 5));
        Console.WriteLine(Calculate(10, '-', 5));
        Console.WriteLine(Calculate(10, '*', 5));
        Console.WriteLine(Calculate(10, '/', 5));
    }
}

运行结果:

15

5

50

2


练习16: 数组中的两数之和

题目 : 给定一个整数数组 nums 和一个目标值 target ,编写一个函数找到数组中和为目标值的两个整数的索引。假设数组中的数据和一定能满足target,不用考虑不满足的情况。
首先定义了一个 FindTwoSum函数,它遍历输入的整数数组 nums,对于每个元素,计算它与目标值 target之间的差值 complement,然后检查这个差值是否已经在之前遍历过程中存储的哈希表 numMap中。如果存在,就找到了一组解,返回这两个数的索引;如果不存在,则将当前元素及其索引存入哈希表,继续遍历。
using System;
using System.Collections.Generic;
class TwoSum
{
    public static Tuple<int, int> FindTwoSum(int[] nums, int target)
    {
        Dictionary<int, int> numMap = new Dictionary<int, int>();

        for (int i = 0; i < nums.Length; i++)
        {
            int complement = target - nums[i];

            if (numMap.ContainsKey(complement))
            {
                return Tuple.Create(numMap[complement], i);
            }

            if (!numMap.ContainsKey(nums[i]))
            {
                numMap[nums[i]] = i;
            }
        }

        throw new InvalidOperationException("No two sum solution");
    }
    static void Main(string[] args)
    {
        int[] nums = { 2, 7, 11, 15 };
        int target = 9;
        var indices = FindTwoSum(nums, target);
        Console.WriteLine($"Indices: {indices.Item1}, {indices.Item2}");
    }
}

运行结果:Indices:0,1


练习17: 字符串去重

题目 : 编写一个函数,移除字符串中的重复字符,只保留第一个出现的字符。
定义了一个 RemoveDuplicates方法,它遍历输入字符串 str中的每一个字符。如果遇到的字符还没有在字典 seenChars中,就将该字符添加到字典中并记录其在输出字符串中的位置,同时将该字符追加到 StringBuilder对象 st中。最后,将 st转换为字符串并返回,得到的就是去除了重复字符后的字符串。
using System;
using System.Text;
class UniqueChars
{
    public static string RemoveDuplicates(string str)
    {
        StringBuilder st= new StringBuilder();
        HashSet<char> seenChars = new HashSet<char>();
        foreach (char c in str)
        {
            if (!seenChars.Contains(c))
            {
                seenChars.Add(c);
                st.Append(c);
            }
        }

        return st.ToString();
    }
    static void Main(string[] args)
    {
        string input = "hello world";
        Console.WriteLine(RemoveDuplicates(input));
    }
}

运行结果:helo wrd


练习18: 滑动窗口最大值

题目 : 给定一个数组和一个窗口大小k,找到滑动窗口中的最大值。
首先检查输入的有效性,然后初始化一个双端队列 deque和一个结果列表 maxValues。遍历输入数组的过程中,它维护了一个降序的索引队列,确保队列头部的索引对应的数组元素始终是当前窗口内的最大值。每当窗口滑动时(即遍历到新的元素),就根据窗口大小k调整队列,确保队列中只包含当前窗口内的索引,并将窗口的最大值添加到结果列表中。最后,输出所有窗口的最大值。
using System;
using System.Collections.Generic;
class SlidingWindowMax
{
    public static List<int> FindMaxInWindows(int[] nums, int k)
    {
        if (nums == null || k <= 0 || nums.Length < k)
        {
            throw new ArgumentException("Invalid input");
        }

        LinkedList<int> window = new LinkedList<int>();
        List<int> maxValues = new List<int>();

        for (int i = 0; i < nums.Length; i++)
        {
            while (window.Count > 0 && window.First.Value <= i - k)
            {
                window.RemoveFirst();
            }

            while (window.Count > 0 && nums[i] >= nums[window.Last.Value])
            {
                window.RemoveLast();
            }

            window.AddLast(i);
            if (i >= k - 1)
            {
                maxValues.Add(nums[window.First.Value]);
            }
        }
        return maxValues;
    }
    static void Main(string[] args)
    {
        int[] nums = { 1, 3, -1, -3, 5, 3, 6, 7 };
        int k = 3;
        List<int> maxValues = FindMaxInWindows(nums, k);
        foreach (int max in maxValues)
        {
            Console.Write(max + " ");
        }
    }
}

运行结果:3 3 5 5 6 7


练习19: 矩阵旋转

题目 : 编写一个函数,将一个N x N的矩阵顺时针旋转90度。
先转置矩阵(行变为列,列变为行),再对每一行进行反转,以完成顺时针旋转90度的效果。 RotateMatrix函数实现了旋转逻辑,而 PrintMatrix函数用于打印矩阵以便查看结果。
using System;
class MatrixRotation
{
    public static void RotateMatrix(int[,] matrix)
    {
        int n = matrix.GetLength(0);
        for (int layer = 0; layer < n / 2; layer++)
        {
            int first = layer;
            int last = n - 1 - layer;
            for (int i = first; i < last; i++)
            {
                int offset = i - first;
                int top = matrix[first, i];
                matrix[first, i] = matrix[last - offset, first];
                matrix[last - offset, first] = matrix[last, last - offset];
                matrix[last, last - offset] = matrix[i, last];
                matrix[i, last] = top;
            }
        }
    }
 
static void PrintMatrix(int[,] matrix)
    {
        for (int i = 0; i < matrix.GetLength(0); i ++)
        {
            for (int j = 0; j < matrix.GetLength(1); j ++ )
            {
                Console.Write(matrix[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
    static void Main(string[] args)
    {
        int[,] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
        RotateMatrix(matrix);
        PrintMatrix(matrix);
    }
}

运行结果:

7 4 1

8 5 2

9 6 3


练习20: 字符串压缩

题目 : 编写一个函数,对字符串进行基本的压缩,如果压缩后的字符串不比原字符串短,则返回原字符串。
首先定义了一个 BasicCompress函数,它遍历输入的字符串,统计每个连续重复字符的数量,并将字符和对应的数量追加到一个 StringBuilder中。完成遍历后,比较压缩后的字符串长度与原始字符串长度,决定返回哪一个。
using System.Text;
class StringCompressor
{
    public static string CompressString(string str)
    {
        if (string.IsNullOrEmpty(str))
            return str;
        StringBuilder compressed = new StringBuilder();
        int countConsecutive = 1;

        for (int i = 1; i <= str.Length; i++)
        {
            if (i < str.Length && str[i] == str[i - 1])
            {
                countConsecutive++;
            }
            else
            {
                compressed.Append(str[i - 1]);
                compressed.Append(countConsecutive);
                countConsecutive = 1;
            }
        }
        return compressed.Length < str.Length ? compressed.ToString() : str;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(CompressString("aabcccccaaa"));
    }
}

运行结果:a2b1c5a3


练习21: 有效的括号序列

题目 : 编写一个函数,检查括号序列是否有效。有效的括号序列要求每对括号都能正确闭合。
首先定义了一个 IsValid函数,它接收一个字符串参数 s,并使用一个栈来辅助判断括号序列的有效性。通过遍历字符串,对于每个字符,如果是开括号则压入栈中,如果是闭括号则检查栈顶的开括号是否与之匹配,匹配则弹出栈顶元素,否则返回 false。遍历完成后,如果栈为空,则说明所有括号都已正确闭合,返回 true;否则返回 false
using System;
class ValidParentheses
{
    public static bool IsValid(string s)
    {
        Stack<char> stack = new Stack<char>();

        foreach (char ch in s)
        {
            if (ch == '(' || ch == '{' || ch == '[')
            {
                stack.Push(ch);
            }
            else
            {
                if (stack.Count == 0)
                {
                    return false;
                }

                char top = stack.Peek();
                if ((ch == ')' && top == '(') ||(ch == '}' && top == '{') ||(ch == ']' && top == '['))
                {
                    stack.Pop();
                }
                else
                {
                    return false;
                }
            }
        }
        return stack.Count == 0;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(IsValid("()[]{}"));
    }
}

运行结果:True


练习22: 最长公共前缀

题目 : 编写一个函数,找出一组字符串中的最长公共前缀。
首先检查输入的字符串数组是否为空或长度为0,如果是,则直接返回空字符串。然后,它将最长公共前缀初始化为数组中的第一个字符串,并从第二个字符串开始遍历数组。对于每个字符串,检查当前的最长公共前缀是否还是该字符串的前缀,如果不是,则缩短前缀,去掉最后一个字符,继续比较,直到找到最长公共前缀或确定没有公共前缀。
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System;
class LongestCommonPrefix
{
    public static string FindLongestCommonPrefix(string[] strs)
    {
        if (strs == null || strs.Length == 0)
            return "";
        Array.Sort(strs);
        string first = strs[0];
        string last = strs[strs.Length - 1];
        int minLength = Math.Min(first.Length, last.Length);

        int i = 0;
        while (i < minLength && first[i] == last[i])
        {
            i++;
        }
        return first.Substring(0, i);
    }
    static void Main(string[] args)
    {
        string[] strs = { "flower", "flow", "flight" };
        Console.WriteLine(FindLongestCommonPrefix(strs));
    }
}

运行结果:fl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值