同样,我还在处理递归,我对其中一个基本案例有疑问。
UPD:a和b代表序列中的第一个数字,n是待计算总和的理想位置。
我的代码如下:
public static int fib(int a, int b, int n) {
if (n <=1) {
return a;
} else if (n == 2) {
return b;
} else {
return (fib(a, b, n - 1) + fib(a, b, n - 2));
}
}
在第2行,在我开始手动追踪程序之前,我将其保持为“n <= 0”。但是,当我跟踪并运行程序时,我得到了一个差异答案。问题是在某个时刻n将= 1。所以我将第一个基本案例改为n&lt; = 1并得到了相同的答案。
现在的问题是,假设我调用了如下方法:fib(2,3,6) 答案应该是= 21(第2行=“n <= 1”) 但当第2行为“n <= 0”时,答案是27。
我想知道在第2行给出“n&lt; = 0”时n最终= 1时程序会发生什么
答案 0 :(得分:1)
当n为1时的调用将产生两个额外的递归调用,其中n为0,n为-1。这两个递归调用会将a
两次添加到正确的答案中。
答案 1 :(得分:0)
要获得第n个Fibonacci,只需将n传递给函数。
假设序列为0,1,1,2,3 ......
您的算法将
if n = 1 return 0
else if n = 2 return 1
else return fib(n - 2) + fib(n - 1)
答案 2 :(得分:0)
我实际上回答了我自己的问题。
你看到n = 3, 因此,要返回的值最终将导致n = 1,如下所示:
返回(Fib(2,3,2)+ Fib(2,3,1))
现在n = 1,第2行的基本情况将正确执行。
而如果第2行中的基本情况是“n <= 0”,那么对于n = 3
的情况返回(Fib(2,3,2)+ Fib(2,3,1))
然后Fib(2,3,1)将再次调用该方法并导致n = 0,这将导致 n = -1&amp; n = -2 导致答案不同。
// UpDATED:n = 0&amp; n = -1将导致答案不同
答案 3 :(得分:0)
你有两个基本情况,两个都会最终命中,而不是返回n,这是正确的,它返回一个传递和未更改的变量a
或b
。
您的代码是计算斐波纳契系列的两种不同方式的混乱组合。 你有一个非常低效的递归:
public static int fib(int n) {
if (n <=1)
return n;
return fib(n-1) + fib(n-2);
}
但是,正如你所看到的那样,它将计算所有重要时刻。如果您看到序列,则可以通过将两个数字a和b作为参数从头开始迭代:
a 0 1 1 2 3 5 ...
b 1 1 2 3 5 8 ...
要计算下一个a,请使用b。要计算新a,请添加a和b。因此,更有效的算法是:
public static int fib(int a, int b, int n) {
if (n <= 0)
return a;
return fib(b, a+b, n-1);
}
Java没有尾部调用优化,因此递归不会像其他优化尾调用的语言那样有效,因此非递归版本会更好,例如:
public static int fib(int n) {
for(int a=0, b=1;; n--) {
if (n <= 0)
return a;
int tmpa = a;
a = b;
b += tmpa;
}
}