C#经典算法面试题

1.递归算法

1.1 C#递归算法计算阶乘的方法

一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。

原理:亦即n!=1×2×3×...×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。

		/// <summary>
		/// C#递归算法计算阶乘的方法
		/// 一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。1808年,基斯顿·卡曼引进这个表示法。
		/// 亦即n!=1×2×3×...×(n-1)×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
		/// 最终输出结果:120
		/// </summary>
		public static void RecursiveFactorial()
		{
			int result = Factorial(5);
			Console.WriteLine("5的阶乘为:" + result);//5!=120
		}

		public static int Factorial(int n)
		{
			if (n == 0 || n == 1)
			{
				return 1;
			}
			else
			{
				// 递归调用:当前数n乘以前面所有数的阶乘
				return n * Factorial(n - 1);
			}
		}

1.2 C#递归算法数组求

		/// <summary>
		/// 递归算法数组求
		/// 最终输出结果为:259
		/// </summary>
		public static void RecursiveArraySum()
		{
			int[] numbers = { 1, 88, 66, 4, 100 };
			int sum = ArraySum(numbers, 0);
			Console.WriteLine("数组元素的总和为:" + sum);
		}

		/// <summary>
		/// 计算数组元素的总和
		/// </summary>
		/// <param name="arr">arr</param>
		/// <param name="index">index</param>
		/// <returns></returns>
		public static int ArraySum(int[] arr, int index)
		{
			if (index >= arr.Length)
			{
				// 基本情况:数组为空或者已经遍历完所有元素
				return 0;
			}
			else
			{
				// 递归调用:当前元素加上剩余元素的总和
				return arr[index] + ArraySum(arr, index + 1);
			}
		}

1.3 C#使用递归算法来实现求解斐波纳契数列中第30位数的值

一列数的规则如下 : 1 、 1 、 2 、 3 、 5 、 8 、 13 、 21 、 34… 求第 30 位数是多少, 用递归算法实现。

		/// <summary>
		/// 使用递归算法来实现求解斐波纳契数列中第30位数的值
		/// 一列数的规则如下 : 1 、 1 、 2 、 3 、 5 、 8 、 13 、 21 、 34… 求第 30 位数是多少, 用递归算法实现
		/// 最终输出结果为:832040
		/// </summary>
		public static void FibonacciSum()
		{
			int n = 30;
			int result = Fibonacci(n);
			Console.WriteLine("第 " + n + "位斐波那契数是:" + result);
		}

		public static int Fibonacci(int n)
		{
			if (n <= 0)
			{
				return 0;
			}
			else if (n > 0 && n <= 2)
			{
				return 1;
			}
			else
			{
				// 递归情况:调用自身计算前两个数字之和
				return Fibonacci(n - 1) + Fibonacci(n - 2);
			}
		}

1.4 使用C#语言编写的递归算法来计算1+2+3+4+…+100的结果

		/// <summary>
		/// 使用C#语言编写的递归算法来计算1+2+3+4+…+100的结果
		/// 最终输出结果是:5050
		/// </summary>
		public static void RecursiveAlgorithmSum()
		{
			int result = SumNumbers(100);
			Console.WriteLine("1+2+3+4+...+100 = " + result);
		}

		public static int SumNumbers(int n)
		{
			if (n == 1)
			{
				return 1;//递归结束条件
			}
			else
			{
				return n + SumNumbers(n - 1);
			}
		}

2.C#常见排序算法

2.1 冒泡排序算法

双重循环方式实现冒泡排序

		/// <summary>
		/// 双重循环方式实现冒泡排序
		/// </summary>
		public static void BubbleSort()
		{
			int[] arr = { 1, 8, 9, 5, 6, 2, 3, 4, 7 };
			int arrLength = arr.Length;
			for (int i = 0; i < arrLength - 1; i++)
			{
				for (int j = 0; j < arrLength - i - 1; j++)
				{
					if (arr[j] > arr[j + 1])
					{
						//交换arr[j]和arr[j+1]的值
						int temp = arr[j];
						arr[j] = arr[j + 1];
						arr[j + 1] = temp;
					}
				}
			}

			Console.WriteLine("排序后结果:" + string.Join(", ", arr));
		}

递归方式实现冒泡排序

		/// <summary>
		/// 递归方式实现冒泡排序
		/// </summary>
		/// <param name="arr">arr</param>
		/// <param name="arrLength">arrLength</param>
		public static void RecursiveBubbleSort(int[] arr, int arrLength)
		{
			if (arrLength == 1)
				return;

			for (int i = 0; i < arrLength - 1; i++)
			{
				if (arr[i] > arr[i + 1])
				{
					//交换arr[i]和arr[i+1]的值
					int temp = arr[i];
					arr[i] = arr[i + 1];
					arr[i + 1] = temp;
				}
			}

			RecursiveBubbleSort(arr, arrLength - 1);
		}

		public static void RecursiveBubbleSortRun()
		{
			int[] arr = { 1, 8, 9, 5, 6, 2, 3, 4, 7 };
			int arrLength = arr.Length;
			RecursiveBubbleSort(arr, arrLength);
			Console.WriteLine("排序后结果:" + string.Join(", ", arr));
		}

2.2 选择排序算法

选择排序是一种简单直观的排序算法,它的工作原理如下: 选择排序算法的核心思想是每次从未排序的部分中找到最小元素,然后将其与未排序部分的第一个元素交换位置。通过不断进行这个过程,逐步将最小元素放到正确的位置,完成整个数组的排序。

	public class 选择排序算法
	{
		/// <summary>
		/// 选择排序算法
		/// 选择排序算法的核心思想是每次从未排序的部分中找到最小元素,然后将其与未排序部分的第一个元素交换位置。
		/// 通过不断进行这个过程,逐步将最小元素放到正确的位置,完成整个数组的排序。
		/// </summary>
		public static void SelectionSortAlgorithmMain()
		{
			int[] array = { 64, 25, 12, 22, 11 };

			Console.WriteLine("原始数组: ");
			PrintArray(array);

			SelectionSortAlgorithm(array);

			Console.WriteLine("排序后的数组: ");
			PrintArray(array);
		}

		static void SelectionSortAlgorithm(int[] arr)
		{
			int n = arr.Length;

			for (int i = 0; i < n - 1; i++)
			{
				// 在未排序部分中找到最小元素的索引
				int minIndex = i;
				for (int j = i + 1; j < n; j++)
				{
					if (arr[j] < arr[minIndex])
					{
						minIndex = j;
					}
				}

				// 将最小元素与未排序部分的第一个元素交换位置
				int temp = arr[minIndex];
				arr[minIndex] = arr[i];
				arr[i] = temp;
			}
		}

		static void PrintArray(int[] arr)
		{
			int n = arr.Length;
			for (int i = 0; i < n; ++i)
			{
				Console.Write(arr[i] + " ");
			}
			Console.WriteLine();
		}
	}

3. C#List集合相关

3.1 C#List RemoveAt(按照索引移除)、Remove(按照对象移除)

		/// <summary>
		/// 获取移除后的列表数据
		/// 考察内容:C#List RemoveAt(按照索引移除)、Remove(按照对象移除)
		/// </summary>
		/// <returns></returns>
		public static List<int> GetAfterRemoveListData()
		{
			List<int> list = new List<int>();
			for (int i = 1; i <= 10; i++)
			{
				list.Add(i);
			}

			for (int i = 0; i < 5; i++)
			{
				list.RemoveAt(i);//单独使用输出结果:2,4,6,8,10,按照索引移除
				list.Remove(i);//单独使用输出结果:5,6,7,8,9,10,按照对象移除
			}

			//以上两种同时使用时输出结果:6,7,9
			return list;
		}

4.其他算法

4.1 实现一个方法,对于输入的任意字符串,统计出其中每一种字符出现的次数

/** 字典的定义
 必须包含名空间System.Collection.Generic
 Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)
 键必须是唯一的,而值不需要唯一的
 键和值都可以是任何类型(比如:string, int, 自定义类型,等等)
 通过一个键读取一个值的时间是接近O(1)
 键值对之间的偏序可以不定义
*/
static void CountChar(string str)
{
	Dictionary<char, int> dic = new Dictionary<char, int>();
	foreach (char c in str)
	{
		if (dic.ContainsKey(c))
			dic[c]++;
		else
			dic.Add(c, 1);
	}
	foreach (KeyValuePair<char, int> p in dic)
	{
		Console.WriteLine("字符{0},出现的次数{1}", p.Key.ToString(), p.Value.ToString());
	}
}

4.2 实现一个将字符串转换为整数的方法,不要使用int.Parse、int.TryParse、Convert.ToInt32等任何类库方法

		public static bool TryParseToInt(string strData, out int num)
		{
			if (string.IsNullOrWhiteSpace(strData))
			{
				num = 0;
				return false;
			}
			int result = 0;

			bool minus = strData[0] == '-' ? true : false;
			if (minus && strData.Length == 1)
			{
				num = 0;
				return false;
			}

			for (int i = minus ? 1 : 0; i < strData.Length; i++)
			{
				if (strData[i] >= '0' && strData[i] <= '9')
				{
					result = strData[i] - 48 + result * 10;
				}
				else
				{
					num = 0;
					return false;
				}
			}

			num = minus ? -result : result;
			return true;
		}

		static void Main(string[] args)
		{
			//打印输出getValue为转化而成的整数
			var result = TryParseToInt("99", out int getValue);
		}

4.3 求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m

  //通过顺序规律写程序,同时也知道flag标志位的重要性
  static int F1(int m)  
	{  
		int sum =0;  
		bool flag =true;  
		for (int i = 1; i <= m; i++)  
		{  
			if (flag)  //一次是默认是True,下下也为True  
				sum += i;  
			else  
				sum -= i;  
			flag = !flag;  

		}  
		return sum;  
	}  

	//通过奇偶性  
	static int F2(int m)  
	{  
		int sum = 0;  
		for (int i = 1; i <= m; i++)  
		{  
			if (i % 2 >0)  //即为奇数  
				sum += i;  
			else  
				sum -= i;  
		}  
		return sum;  
	}  

4.4 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

 class Program  
	{  
		static void Main(string[] args)  
		{  

			//有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?  
			//分解题目  
			//条件:四个数字1、2、3、4  ;三位数:百位、十位、个位  
			//要求:互不相同;无重复数字:每个数字在三位中只出现一次  
			//结果:多少个? 都是多少?  

			int count = 0; //统计个数  
			for (int bw = 1; bw <= 4; bw++)  
			{  
				for (int sw = 1; sw <= 4; sw++)  
				{  
					if (sw!= bw)  //很显然,只有百位和十位不同的情况下才能谈个位。  
					{  
						for (int gw = 1; gw <= 4; gw++)  
						{  
							if (gw != sw && gw != bw)   //百位用过的,十位就不能用;百位和十位都用过的,个位就不能用  
							{  
								count++;  
								Console.WriteLine("{0}{1}{2}", bw, sw, gw);  
							}  
						}  
					}  
				}  
			}  
			Console.WriteLine("一共有{0}个", count);  
			Console.Read();  

		}  
	}   

4.5 一个6位数乘以一个3位数,得到一个结果。但不清楚6位数的两个数字是什么,而且结果中有一位数字也不清楚,请编程找出问好代表的数字,答案可能有多个。

表达式:12?56?*123 = 154?4987

 for (int a = 0; a < 10; a++)  
	{  
		for (int b = 0; b < 10; b++)  
		{  
			for (int c = 0; c < 10; c++)  
			{  
				if ((120560 + a + b * 1000) * 123 == 15404987 + c * 10000)  
				{  
					Console.WriteLine(a);  
					Console.WriteLine(b);  
					Console.WriteLine(c);  
				}  
			}  
		}  
	}  
	Console.Read();  

4.6 有一个字符串 "I am a good man",设计一个函数,返回 "man good a am I"。

		  static string Reverse()  
		  {  
			  string s = "I am a good man";  
			  string[] arr = s.Split(' ');  
			  string res = "";  
			  for (int i = arr.Length - 1; i >= 0; i--)  
			  {  
				  res += arr[i];  
				  if (i > 0)  
					  res += " ";  
			  }  
			  return res;  
		  }  

4.7 C# 九九乘法表算法实现

		 static void Mu()  
		  {  
			  string t = string.Empty;  
			  for (int i = 1; i < 10; i++)  
			  {  
				  for (int j = 1; j <= i; j++)  
				  {  
					  t = string.Format("{0}*{1}={2} ", j, i, (j * i));  
					  Console.Write(t);  
					  //if (j * i < 82)  
					  //    Console.Write(" ");  
					  if (i == j)  
						  Console.Write("\n");  
				  }  
			  }  
		  }  

4.8 在1~10000的整数中,找出同时符合以下条件的数:a.必须是质数。b.该数字各位数字之和为偶数,如数字12345,各位数字之和为1+2+3+4+5=15,不是偶数。

本题考了两个地方: (1)、质数的理解:质数就是所有比1大的整数中,除了1和它本身外,不再有别的约数。2是一个不是奇数的质数,它既是质数也是偶数,面试者极容易忽略这点。判断数N是否为质数要直接从3开始判断(如果N不是2),首先不能是偶数,然后再判断是否能被3、5、7....整除,直到sqrt(N)止。 (2)、求各位数字之和,可以通过循环取余的办法。

 using System;  
	using System.Collections.Generic;  

	class program  
	{  
	   static void Mian(string[] args)  
	   {  
		  int N =1000;  
		  List<int> primes = new List<int>();  
		  primes.Add(2);  
		  Console.Write(2+" ");  
		  for(int i=3;i<N,i+=2)  
		  {  
			  if(!)  

		  }  
	   }  
	   static bool IsDigitSumEven(int n)  
	   {  
		  int sum=0;  
		  while(n>0)  
		 {  
			 sum +=n% 10;  
			 n /=10;  
		 }  
		 return sum%2==0;  
	   } 
	}  
posted @ 2024-12-14 11:31  似梦亦非梦  阅读(24)  评论(0编辑  收藏  举报