【问题标题】:Fibonacci recursive function斐波那契递归函数
【发布时间】:2020-10-12 12:07:33
【问题描述】:

下面的程序旨在使用递归函数打印斐波那契数列的前 25 项。 我得到了输出,但问题是程序没有停止,一旦它们变大,值就会变成负值。

#include <stdio.h>
int fibo(int, int, int);
int main()
{
    int s, c, i;
    s = 1;
    c = 0;
    i = 0;
    fibo(s, c, i);
}
int fibo(int s, int c, int i)
{
    for(i = 0; i <= 25; i++)
    {
        s = s + c;
        c = s - c;
        printf("%d\n", s);
        fibo(s, c, i);
    }
}

预期输出:

1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393

我的输出:

1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
2178309
3524578
5702887
9227465
14930352
24157817
39088169
63245986
102334155
165580141
267914296
433494437
701408733
1134903170
1836311903
-1323752223
512559680
-811192543
-298632863
-1109825406
-1408458269
1776683621
368225352
2144908973
-1781832971
363076002
-1418756969
-1055680967
1820529360
764848393
-1709589543
-944741150
1640636603
695895453
-1958435240
-1262539787
1073992269
-188547518
885444751
...

【问题讨论】:

  • 将数据类型从 int 更改为 long 或大于整数的类型。从技术上讲,斐波那契将从递归中打印多达 45 个。之后,您需要动态编程来打印值。
  • edit 使用正确的编程语言标记(显然是c)。在没有语言标签的情况下,您的问题将获得很少的视图,并且那些确实查看它的人可能不知道 C。
  • per fibonacci sequence 斐波那契数列以:0, 1, 1, 2, 3, 5, 8, 13, 21, 34,... 不是问题所描述的斐波那契数列。斐波那契数列的规则是:xn = xn−1 + xn−2
  • 关于; for(i = 0; i &lt;= 25; i++) 这个循环将迭代 26 次,而不是 25 次。建议:for(i = 0; i &lt; 25; i++)
  • for() 循环,递归将“嵌套”一些 26! (阶乘)次。即使数值没有溢出它们的内容,可用的“堆栈”也会溢出,导致程序崩溃

标签: c recursion fibonacci


【解决方案1】:

您所看到的有两个问题。

第一个问题是函数fibo 中for 循环末尾的递归调用fibo(s,c,i);。你为什么要进行递归调用? for 循环本身完成了所有工作,这里不需要递归。只需删除该行,一切都会正常运行。

第二个问题是整数溢出。如果这是您第一次尝试它,那么恭喜您!简短的解释是 C 类型 int 不能代表我们在数学中所知道的 all 整数;只能表示有限范围的整数。斐波那契数列中的整数很快变得非常大,无法使用int 类型充分表示。当像 s+c 这样的算术运算产生的结果大于可以表示为 int 的最大数时,就会发生整数溢出。这是未定义的行为。在大多数情况下(但不是全部),实际行为是整数“环绕”,因此 largest_integer + 1 == smallest_integer 和当然 smallest_integer 是负数。

如果您在程序中将每次出现的int 替换为long long int,您将能够在序列中看到更多的数字。但是一段时间后数字仍然会变得太大。

另见:

【讨论】:

  • 嘿,谢谢支持,问题是用递归函数打印斐波那契数列,这就是为什么我在for循环的末尾添加了fibo函数。
【解决方案2】:

这个练习的想法是使用递归而不是循环。

不清楚您的三个参数应该代表什么(sci 可能不是信息量最大的变量名称)。但一般来说,非天真的递归斐波那契实现可能如下所示:

int fib(int n, int prev, int curr) {
    if (n == 0) return prev;
    if (n == 1) return curr;
    return fib(n - 1, curr, curr + prev);
}

并打印前 25 个数字:

int main(void) {
    for (int i = 0; i < 25; i++) {
        printf("fib(%d) = %d\n", i, fib(i, 0, 1));
    }
}

注意:这会冗余计算中间结果。删除这种冗余需要在fib 函数内调用printf。但是您通常希望避免混合计算和 IO,而上述方法仍然足够高效,无需这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-01
    • 2010-12-03
    • 2020-03-21
    • 2021-11-17
    • 2011-07-27
    • 2014-11-09
    • 2014-04-02
    相关资源
    最近更新 更多