我的Java递归fibonacci函数有什么问题?

时间:2015-05-12 20:11:21

标签: java recursion fibonacci

我刚刚写了这篇文章,但由于某种原因在控制台中,我得到了一些看起来正确但序列错误的数字,并且重复了一些数字。有什么问题?

public class Fibonacci {
    public static void main(String[] args) {
        int n = 5;

        fibonacci(n);
    }

    public static int fibonacci(int n) {
        if(n == 0) {
            System.out.println(0);
            return 0;
        } else if(n == 1) {
            System.out.println(1);
            return 1;
        } else {
            int result = fibonacci(n - 1) + fibonacci(n - 2);
            System.out.println(result);
            return result;
        }
    }
}

5 个答案:

答案 0 :(得分:1)

如果您希望查看斐波那契序列达到设定的字词,请删除fibonacci(int n)方法中的所有输出,并在{{1}中的main中只有一个print方法}从1循环到你设定的术语。

for

结果:

enter image description here

答案 1 :(得分:0)

您的程序正确计算斐波纳契数。它是在fibonacci的顶级调用中打印的最后一个数字。

有些数字会重复打印,因为它们的计算次数不止一次。 fibonacci(5)调用fibonacci(4) + fibonacci(3),调用fibonacci(3) + fibonacci(2) + fibonacci(2) + fibonacci(1),我们已经有两个具有相同参数的单独递归调用。随着递归调用的进一步下降,会有更多的重复调用。

对于5之类的低输入,这没关系,但是对于更高的数字,您将遇到性能问题,因为此算法本质上是指数级的。复杂性为O(2 n )。您当前的打印语句突出显示正在执行的所有额外计算。您可以删除它们,但算法的复杂性仍然呈指数级。

即使您的程序当前是正确的,也可以通过将中间调用的结果存储到数组中fibonacci来消除指数复杂性,将其替换为线性复杂度(O(n))。这样,每个中间步骤只计算一次。

答案 2 :(得分:0)

我建议您删除这些打印声明。他们让你很困惑。

这是递归的工作方式:你弹出方法调用堆栈来评估它们。

这对我来说很好看:

public class Fibonacci {
    public static void main(String[] args) {
        int n = 10;

        for (int i = 0; i < n; ++i) {
            System.out.println(String.format("i: %5d fib(i): %10d", i, fibonacci(i)));
        }
    }

    public static int fibonacci(int n) {
        if(n == 0) {
            return 0;
        } else if(n == 1) {
            return 1;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

答案 3 :(得分:0)

由于您的函数是递归的,因此每个斐波纳契数有多个打印件。如果您不想这样做,请将打印移到功能

之外
public class Fibonacci {
    public static void main(String[] args) {
        int n = 5;

        System.out.println(fibonacci(n));
    }

    public static int fibonacci(int n) {
        if(n == 0) {
            return 0;
        } else if(n == 1) {
            return 1;
        } else {
            int result = fibonacci(n - 1) + fibonacci(n - 2);
            return result;
        }
    }
}

但是,如果您打算使用打印件来跟踪函数的作用,那么它已经按预期运行。递归的斐波那契计算多次相同的值,这就是它效率低的原因。

答案 4 :(得分:0)

你的方法非常好,额外的打印来自你fibonacci方法的递归调用。 fib for 4的调用堆栈是:

                         f(4)
                  /                 \
          f(4-1)          +            f(4-2)
        /          \                /         \
   f(3-1)   +     f(3-2)  +      f(2-1)  +  f(2-2)
    /      \        |               |          |
 f(2-1) + f(2-2)    |               |          |
    |        |      |               |          |
    1   +    0  +   1      +        1     +    0
                        3

(注意:f是fibonacci

的缩写

每个调用都会打印到控制台,从而产生额外和无序数字。