C#实现斐波拉契数列的两种方式

4 篇文章 0 订阅

C#实现斐波拉契数列的两种方式

在实现代码之前,我们首先来看看斐波拉契数列的由来

斐波那契数列(Fibonacci sequence)

又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。

那什么是兔子数列呢?继续往下看

兔子问题:

历史上有一个有名的关于兔子的问题:假设有一对兔子,长两个月它们就算长大成年了。然后以后每个月都会生出1对兔子,生下来的兔子也都是长两个月就算成年,然后每个月也都会生出1对兔子了。这里假设兔子不会死,每次都是只生1对兔子。

第一个月,只有1对小兔子;

第二个月,小兔子还没长成年,还是只有1对兔子;

第三个月,兔子长成年了,同时生了1对小兔子,因此有两对兔子;

第四个月,成年兔子又生了1对兔子,加上自己及上月生的小兔子,共有3对兔子;

第五个月,成年兔子又生了1对兔子,第三月生的小兔子现在已经长成年了且生了1对小子,加上本身两只成年兔子及上月生的小兔子,共5对兔子;

这样过了一年之后,会有多少对兔子了呢?(思考)

总结:

我们可以把这些兔子的数量以对为单位列出数字就能得到一组数字:1、1、2、3、5、8、13、21、34、55、89、144、233。所以,过了一年之后,总共会有233对兔子了。那么续往下呢?

其实这组数字可以形成一个有规律的数列,我们把这个数列叫做“斐波那契数列”。在这个数列中的数字,就被称为“斐波那契数”。这个数列是在1228年意大利数学家斐波那契首先提出的。这个数列的规律是这样的:它的第一项、第二项是1,而从第三项起每一项都等于它的前两项之和。

实现方式:

第一种方式(递归):

通过重复调用当前方法来进行递归,欲求第n项和第n-1项之和,先求第n-1和n-2项之和…直到得到已知的第一项和第二项的值,再将结果进行回溯,逆推后面的值,得到我们想要的结果值。

此种方法的好处是能够较为直接简便的实现我们需要的功能,且能提高代码的简洁性和可读性,但最大的缺点是运行时间较长(128s),时间复杂度和空间复杂度较高。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FibonacciSort
{
    class Program
    {

        long Fib(int num){

            if (num <3)
            {
                return 1;               
            }
            else
            {
                return Fib(num - 1) + Fib(num - 2);
            }
        }
        static void Main(string[] args)
        {
            //定义一个计时对象
            System.Diagnostics.Stopwatch needTime = new System.Diagnostics.Stopwatch();

            needTime.Start();

            Program Pro = new Program();
             
            Console.WriteLine("第40个元素为:"+ Pro.Fib(40));

            Console.WriteLine("第48个元素为:" + Pro.Fib(48));

            needTime.Stop();

            //运行时间打印
            Console.WriteLine("运行时间:" + needTime.Elapsed.TotalSeconds + "s");


        }
    }
}

运行结果:
运行截图
在这里需要注意,定时器只为记录运行时间,与数列生成实现无关。

第二种方式(递推):

这种方式主要是通过定义三个不同对象,为他们循环赋值累加以得到最终需要的那个值,具体赋值方式如下。

此方法比较不灵活,需要得到某个数时,需要更改循环次数,否则就会造成数组越界或者内存浪费,但是执行速度极快(0.002s)。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Fibonacci1
{
    class Program
    {
        static void Main(string[] args)
        {
            //定义一个计时对象
            System.Diagnostics.Stopwatch needTime = new System.Diagnostics.Stopwatch();   
            needTime.Start();
            long a, b, c;
            a = 1;
            b = 1;

            for(int i = 3; i < 49; i++)
            {
                c = a + b;
                a = b;
                b = c;
                if (i == 40)
                {
                    Console.WriteLine("第40个数为:"+c);
                }
                if (i == 48)
                {
                    Console.WriteLine("第48个数为:"+c);
                }
            }
            needTime.Stop();
            //运行时间打印
            Console.WriteLine("运行时间:"+needTime.Elapsed.TotalSeconds+"s");
        }
    }
}

运行结果:
运行截图
至于两种实现方式到底哪种更好,笔者觉得要视实际情况而定,在合适的场景,选择合适的实现方式吧。

以上就是全部内容,看过给个关注吧。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值