VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 方法重载与递归——用C#斐波那契数列生成器

第一部分:C#基础入门
实例6:方法重载与递归——斐波那契数列生成器
实例介绍
本实例通过斐波那契数列生成器,系统讲解方法重载(同一方法名适配不同场景)和递归(方法自我调用解决问题)的核心概念。你将学会用重载方法灵活生成数列项、前n项数组或格式化字符串,理解递归的简洁性与性能瓶颈,掌握迭代优化技巧,为复杂算法设计打下基础。
需求分析
1.多场景生成:支持生成第n项、前n项数组、带格式的字符串(如逗号分隔);
2.方法重载:用同一方法名Fibonacci适配不同参数需求;
3.递归与迭代对比:展示递归的简洁性与迭代的高性能;
4.边界处理:处理n=0、n=1、负数输入等特殊情况;
5.性能提示:警告递归对大n的栈溢出风险,提供优化方向。
代码实现
csharp

	using System;
	using System.Text;
	
	namespace MethodOverloadAndRecursionDemo
	{
	class FibonacciGenerator
	{
	// 备忘录:优化递归(保存已计算项,避免重复计算)
	private static readonly Dictionary<int, long> _fibMemo = new Dictionary<int, long>();
	
	static void Main(string[] args)
	{
	Console.Write("请输入斐波那契数列的项数n(正整数):");
	if (!int.TryParse(Console.ReadLine(), out int n) || n < 1)
	{
	Console.WriteLine("输入无效!n必须是正整数。");
	Console.ReadKey();
	return;
	}
	
	// 1. 用重载方法生成第n项(递归实现)
	long nthTerm = Fibonacci(n);
	Console.WriteLine($"第{n}项(递归):{nthTerm}");
	
	// 2. 用重载方法生成前n项数组(迭代实现)
	long[] fibArray = Fibonacci(n, true);
	Console.WriteLine($"前{n}项数组:[{string.Join(", ", fibArray)}]");
	
	// 3. 用重载方法生成格式化字符串(逗号分隔)
	string fibStr = Fibonacci(n, "comma");
	Console.WriteLine($"前{n}项字符串:{fibStr}");
	
	// 4. 迭代实现对比(性能更高)
	long nthTermIter = FibonacciIterative(n);
	Console.WriteLine($"第{n}项(迭代):{nthTermIter}");
	
	Console.WriteLine("
按任意键退出...");
	Console.ReadKey();
	}
	
	#region 方法重载:同一方法名适配不同需求
	/// <summary>
	/// 重载1:生成斐波那契数列第n项(递归+备忘录优化)
	/// </summary>
	public static long Fibonacci(int n)
	{
	if (n < 0) throw new ArgumentOutOfRangeException(nameof(n), "n不能为负数");
	// 终止条件:F(0)=0,F(1)=1
	if (n <= 1) return n;
	// 备忘录:已计算过的项直接返回
	if (_fibMemo.ContainsKey(n)) return _fibMemo[n];
	// 递归调用:问题规模缩小(n→n-1、n-2)
	long result = Fibonacci(n - 1) + Fibonacci(n - 2);
	_fibMemo[n] = result;
	return result;
	}
	
	/// <summary>
	/// 重载2:生成前n项数组(迭代实现)
	/// </summary>
	public static long[] Fibonacci(int n, bool returnArray)
	{
	if (!returnArray) throw new ArgumentException("参数returnArray必须为true");
	if (n < 1) throw new ArgumentOutOfRangeException(nameof(n));
	
	long[] array = new long[n];
	if (n >=1) array[0] =0; // F(0)
	if (n >=2) array[1] =1; // F(1)
	
	// 迭代计算:用循环替代递归,性能更高
	for(int i=2; i<n; i++)
	{
	array[i] = array[i-1] + array[i-2];
	}
	return array;
	}
	
	/// <summary>
	/// 重载3:生成前n项格式化字符串(如逗号分隔)
	/// </summary>
	public static string Fibonacci(int n, string format)
	{
	if (string.IsNullOrEmpty(format)) throw new ArgumentNullException(nameof(format));
	long[] array = Fibonacci(n, true); // 复用重载2的逻辑
	
	switch(format.ToLower())
	{
	case "comma":
	return string.Join(", ", array);
	case "line":
	return string.Join(Environment.NewLine, array);
	default:
	throw new ArgumentException($"不支持的格式:{format}");
	}
	}
	#endregion
	
	/// <summary>
	/// 迭代实现:生成第n项(无递归,性能最优)
	/// </summary>
	public static long FibonacciIterative(int n)
	{
	if (n <0) throw new ArgumentOutOfRangeException(nameof(n));
	if (n <=1) return n;
	
	long prevPrev =0; // F(n-2)
	long prev =1; // F(n-1)
	long current =0; // F(n)
	
	for(int i=2; i<=n; i++)
	{
	current = prevPrev + prev;
	prevPrev = prev;
	prev = current;
	}
	return current;
	}
	}
	}

逐行讲解

  1. 方法重载核心:同一方法名适配不同参数
    重载规则:同一类中,方法名相同,参数列表(类型、数量、顺序)不同。例如:
    oFibonacci(int n):参数为int,返回第n项;
    oFibonacci(int n, bool returnArray):参数为int+bool,返回前n项数组;
    oFibonacci(int n, string format):参数为int+string,返回格式化字符串。
    好处:无需记忆多个方法名,代码更简洁易读。
  2. 递归实现(带备忘录优化)
    csharp
	public static long Fibonacci(int n)
	{
	if (n <=1) return n; // 终止条件:F(0)=0,F(1)=1
	if (_fibMemo.ContainsKey(n)) return _fibMemo[n]; // 复用已计算项
	long result = Fibonacci(n-1)+Fibonacci(n-2); // 递归调用:规模缩小
	_fibMemo[n] = result; // 保存结果到备忘录
	return result;
	}

递归三要素:
1.终止条件:n<=1时直接返回,避免无限递归;
2.递归调用:Fib(n-1)+Fib(n-2),问题规模从n缩小到n-1和n-2;
3.备忘录优化:用字典保存已计算项,将时间复杂度从O(2^n)降到O(n)。
3. 迭代实现(性能最优)
csharp

	public static long FibonacciIterative(int n)
	{
	if (n<=1) return n;
	long prevPrev=0, prev=1, current=0;
	for(int i=2; i<=n; i++)
	{
	current = prevPrev + prev;
	prevPrev = prev;
	prev = current;
	}
	return current;
	}

逻辑:用三个变量保存F(n-2)、F(n-1)、F(n),循环更新直到第n项;
优势:无递归栈开销,时间复杂度O(n),空间复杂度O(1),适合大n(如n=1000)。
4. 重载方法复用
Fibonacci(n, "comma")调用Fibonacci(n, true)生成数组,再转成逗号分隔字符串;
复用原则:避免重复代码,让重载方法调用基础实现。
基础知识拓展

  1. 方法重载的深层规则
    规则 示例 是否合法
    参数类型不同 Fib(int) vs Fib(long) ✅
    参数数量不同 Fib(int) vs Fib(int, bool) ✅
    参数顺序不同 Fib(int, string) vs Fib(string, int) ✅
    返回类型不同(参数相同) long Fib(int) vs int Fib(int) ❌(编译器无法区分)
    修饰符不同(参数相同) public Fib(int) vs private Fib(int) ❌(编译器无法区分)
  2. 递归的优缺点
    优点:代码简洁,符合数学思维(斐波那契的定义直接对应递归逻辑);
    缺点:
    性能低:重复计算(无备忘录时)+ 栈溢出风险(n>1000时递归深度过大);
    调试难:栈帧嵌套多,错误定位复杂。
  3. 斐波那契数列的数学定义
    标准定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2);
    常见误区:有些资料将F(1)=1、F(2)=1作为起始,需根据需求调整终止条件。
  4. 递归优化方向
    备忘录模式:如代码中的_fibMemo字典,保存已计算项;
    尾递归优化:C#不直接支持,但可通过尾递归改写(将递归调用放在方法最后);
    迭代替代:对于线性递归(如斐波那契),迭代是最优解。
    扩展思考
    1.大数支持:用System.Numerics.BigInteger替代long,处理n>90的超大项(long最大值约9e18,F(90)=2880067194370816120);
    2.备忘录线程安全:给_fibMemo加锁(lock(_fibMemo)),支持多线程环境;
    3.性能对比工具:用Stopwatch测试n=50时递归(备忘录)、迭代的时间差;
    4.生成文件:将前n项保存到文本文件(每行一项);
    5.尾递归改写:尝试将递归方法改为尾递归(如Fib(n, a, b),其中a=F(n-2),b=F(n-1))。
    总结
    本实例通过斐波那契数列,串联了方法重载(灵活适配场景)和递归(简洁解决问题)两大核心知识点。你需记住:
    重载:用同一方法名适配不同参数,提升代码可读性;
    递归:优先考虑简洁性,但需注意性能与栈溢出风险,大n场景用迭代或备忘录优化;
    工程实践:复杂算法需平衡简洁性与性能,复用代码是关键。

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49397.html


相关教程