我刚刚写了这篇文章,但由于某种原因在控制台中,我得到了一些看起来正确但序列错误的数字,并且重复了一些数字。有什么问题?
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;
}
}
}
答案 0 :(得分:1)
如果您希望查看斐波那契序列达到设定的字词,请删除fibonacci(int n)
方法中的所有输出,并在{{1}中的main中只有一个print
方法}从1循环到你设定的术语。
for
结果:
答案 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
)
每个调用都会打印到控制台,从而产生额外和无序数字。