繁体   English   中英

斐波那契程序未完成执行

[英]Fibonacci program does not complete execution

问题描述

通过考虑斐波那契数列中值不超过四百万的项,找到偶值项的总和

程序

using System;

class fibonacci {
    // function to return Nth value of fibonacci
    public static long fibo_n(long N) {
        long fibon=0;
        switch (N) {
            case 1: fibon=1; break;
            case 2: fibon=2; break;
        }
        while(N>2) {
        fibon=fibo_n(N-1)+fibo_n(N-2);
        }
    return fibon;
    }
}    

class fibo_tester {
    static void Main() {
        int N=2;
        long sum=0;
        while(fibonacci.fibo_n(N) <= 13) {
            sum = sum + fibonacci.fibo_n(N);
            N=N+3;
        }
        Console.WriteLine("Sum is {0}: ", sum);
    }
}

我将测试的数量从原来的400万减少到13,但是仍然挂起。 有人可以请教吗?

编辑2

switch (N) {
        case 1: fibon=1; break;
        case 2: fibon=2; break;
        default: fibon=fibo_n(N-1)+fibo_n(N-2); break;
    }
 while(N>2) {
        fibon=fibo_n(N-1)+fibo_n(N-2);
        }

无限循环,N永远不会在循环中更新。 您可能需要删除While()子句并将其全部更改以return fibo_n(N-1)+fibo_n(N-2); 我不确定您在使用switch语句等做什么。但这应该是一个开始。

我实际上将其替换为此(如果您想使用该开关):

class fibonacci
{
    // function to return Nth value of fibonacci
    public static long fibo_n(long N)
    {
        switch (N)
        {
            case 0:
                return 0;
            case 1:
                return 1;
            default:
                return fibo_n(N - 1) + fibo_n(N - 2);
        }
    }
}   

您可能需要考虑将N的每个值的值存储在字典或某种类型的集合中,以便以后查找它们。 由于在您的主程序中,您似乎将遍历这些值(可能已经计算出了较大的N)。 我不确定主循环中的N + 3是什么,但是您可能会错过那里的东西(递归中对N-1和N-2的错误假设?)

另外,如果求和并依赖于您的平台以及要测试的值的大小(测试您的第一个X斐波纳契数的总和),您可能必须使用ulong或查找一些可以处理更大数字的数据类型。 如果我没有在系统上将所有内容从长久更改为冗长的内容,那么这些值就会回绕。 无论如何,斐波那契数不能为负,所以为什么不使用ulong或uint64或更多位。

您同时使用循环和递归-您需要选择一个或另一个。 您的代码中的问题点在这里:

while (N>2) {
    fibon = fibo_n(N-1)+fibo_n(N-2);
}

在这个位置上, N的值实际上不会改变-这是在递归步骤中发生的。 编写此代码的一个示例(不好)方法是:

public static long fibo_n(long N) {
    if (N <= 0) return 0;
    if (N == 1) return 1;
    if (N <= 4) return N - 1;

    return fibo_n(N-1) + fibo_n(N-2);
}

祝你好运!


效果说明:

这不是一个好方法的原因是因为函数调用使用C#中的内存,而且它们也需要时间。 循环总是比递归快,在这种情况下,没有充分的理由通过递归来解决这个问题(与简单的循环相反)。 我将代码保留不变,以便您可以与现有代码进行比较,但是我认为您可以在其他地方找到更好的更好的代码选项(尽管并非所有这些代码都在C#中)。

假设您用等于3的N调用方法。

开关不执行任何操作。

N大于2,因此我们进入while循环。 while循环会执行某些操作; 它计算一个值,并将其分配给fibon 然后,由于N不变,它仍然大于2,因此我们再次对其进行了计算。 它仍然会大于2,因此我们再次进行了计算。 我们永远不会停止计算它。

每次为fibon分配一个值时,您应该返回该值,因为操作已经完成。 您没有什么可计算的。 也不需要while循环。 您永远不需要执行该代码一次以上。

你的实现也效率低下。 要计算fib(5),请计算fib(4)和fib(3)。 然后在计算fib(4)时,再次计算fib(3)和fib(2),当两次计算fib(3)时,它们每次都计算fib(2)(因此是三倍),如果执行数学运算最终导致您在计算fib(n)时执行2 ^ n次计算。 最重要的 ,您正在调用fib n次,因为您在主循环中从零开始计数。 那就是无数次的工作和无数次的工作重新计算了相同的值。 如果只有一个简单的循环将数字加在一起,则可以按N次计算的顺序来计算结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM