【问题标题】:Fibonacci Recursion Not working [duplicate]斐波那契递归不起作用[重复]
【发布时间】:2018-06-22 12:48:00
【问题描述】:

我可能犯了一些愚蠢的错误,但是每当我尝试运行这个程序时,它总是给我一个错误的答案。例如,我问斐波那契数列的第 5 个值是多少,它说 7。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

     // TODO add your handling code here:
    int n=0;
    try{
        n= Integer.parseInt(jTextField1.getText());    
    }
    catch(NumberFormatException e){
        jTextField2.setText("Please enter valid integers.");
    }
    jTextField2.setText("Fibo value is"+Fibonacci(n));
}  

private int Fibonacci(int n){

    System.out.println(n+"N");
    if (n <=1) {
        return n;
    }
    else{
        return Fibonacci(n-1)+(n-2);        
    }
}

【问题讨论】:

  • Fibonacci(n-1) + Fibonacci(n-2);
  • 在实现递归程序时,请尝试在论文中手动扩展定义并查看发生了什么。

标签: java recursion


【解决方案1】:

Fib 递归定义为Fib(n) = Fib(n-1) + Fib(n-2)。 您的程序将其定义为Fib(n) = Fib(n-1) + (n-2)

答案:

int Fibonacci(int n) {

    System.out.println(n + "N");

    if (n <= 1) {
        return n;
    } else {
        return Fibonacci(n - 1) + Fibonacci(n - 2);
    }

}

【讨论】:

    【解决方案2】:

    您正试图通过二进制递归找到斐波那契。您应该进行两次递归调用,例如

    return Fibonacci(n - 1) + Fibonacci(n - 2);
    

    但你在这里犯了一个错误-

    return Fibonacci(n - 1) + (n - 2);
    

    您的代码可以通过

    轻松修复
    int Fibonacci(int n) {
        if (n <= 1)
            return 1;
        else
            return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
    

    上述递归称为二元递归,因为它进行两次递归调用而不是一次。 让我们计算计算第 k 个斐波那契数所需的调用次数:- 让 nk 表示执行中执行的调用次数。

    n0 = 1
    n1 = 1
    n2 = n1 + n0 + 1 = 3 > 21
    n3 = n2 + n1 + 1 = 5 > 22
    n4 = n3 + n2 + 1 = 9 > 23
    n5 = n4 + n3 + 1 = 15 > 23 ...
    nk > 2k/2

    这意味着斐波那契递归进行了许多以 k 为指数的调用。
    换句话说,使用二进制递归来计算斐波那契数是非常低效的。

    这个线性递归版本需要 O(n) 次调用。

    更有效的解决方案:-

    int fibonacci(int n) { 
       return fibonacciSlave(0, 1, n);
    }
    
    int fibonacciSlave(int a, int b, int n) { 
        if(n <= 1) {
           return b;
        }
       return fibonacciSlave(b, a+b, n-1);
    }
    

    【讨论】:

    • 问题不在于如何提高效率,而在于他目前的解决方案有什么问题。我投了反对票,因为你没有解释后者。
    • 我已经在评论中发布了。这是一个非常琐碎的问题。不过,我会添加一些解释。
    • 谢谢,我已经删除了反对票。
    • 感谢您强迫我改进答案:)
    • @AjahnCharles,我采纳了你的建议
    猜你喜欢
    • 2010-12-03
    • 2014-04-02
    • 2017-11-18
    • 2014-01-08
    • 2011-12-14
    • 2012-11-29
    • 2018-04-10
    • 2016-02-21
    相关资源
    最近更新 更多