C语言入门——求斐波那契数

        斐波那契数列,又称黄金分割数列,因数学家莱昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……斐波那契数列:前两个数之和等于第三个数

根据以上描述,我们可以得出求斐波那契数的公式:

Fib(n)=\begin{cases} & \text{ 1} {\, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, \, }n\leq 2 \\ & \text{ \textit{Fib}(n-1)+\textit{Fib}(n-2)} n>2 \end{cases}

有了以上公式,求斐波那契数我们可以用递归实现,如:我们要求斐波那切数列的第n个数,可以用以下代码实现:

#include <stdio.h>
int Fib(int n)
{
    if (n <= 2)
        return 1;
    else
        return (Fib(n - 1) + Fib(n - 2));
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fib(n);
    printf("%d\n", ret);
    return 0;
}

我们求第9菲波那切数,其运行结果如下:

但是如果我们用以上代码求菲波那切数列的第50个数的话,该代码至少要运行3分钟以上(虽然结果是错误的,因为第50个斐波那契数已经超出了int的范围),所以其效率太低,究其原因是什么呢?

我们会发现在递归的时候,会进行大量重复的计算,例如我们要求\textit{Fib}(6),则需要求5次\textit{Fib}(2)

在以上代码我们设置一个计数器count,我们统计一下在求第40个斐波那契数的过程中,会计算多少次第3个斐波那契数?

#include <stdio.h>
int count = 0;
int Fib(int n)
{
    if (n == 3)
    {
        count++;
    }
    if (n <= 2)
        return 1;
    else
        return (Fib(n - 1) + Fib(n - 2));
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fib(n);
    printf("%d\n", ret);
    printf("count = %d\n", count);
    return 0;
}

我们看到count=39088169,可以看到进行了大量重复的计算!

因此,我们可以考虑使用迭代来计算,设置3个变量a、b、c,前两个分别是数列的前两个值1、1,当要求第n(n>=2)个数的时候,设置循环,把前两变量的和放到c中,把b的值赋给a,再把c的值赋给b,最终c里面存放的就是要求的结果

#include <stdio.h>
int Fib(int x)
{
    int a = 1;
    int b = 1;
    int c = 1;
    while(x > 2)
    {
        c = a + b;
        a = b;
        b = c;
        x--;
    }
    return c;
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fib(n);
    printf("%d\n",ret);
    return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值