你对
fibonacci
程序的修改确实可以计算出总和。但是,你使用递归的方式效率较低。一种解决方法是采用“动态规划”方法,将计算出的值缓存,以便第二个递归调用可以重复使用它们。然而,第 n 个斐波那契数可以从基础开始向前计算。其递归实现如下:
public static int fib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return fib_r(b, a+b, n-1);
}
public static int fib (int n) {
return fib_r(0, 1, (n > 0) ? n : 1);
}
求和的相应代码如下:
public static int sumfib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return sumfib_r(b, a+b+1, n-1);
}
public static int sumfib (int n) {
return sumfib_r(0, 1, (n > 0) ? n : 1);
}
尾递归往往会被编译器/解释器作为尾调用移除的一部分而转换成简单的循环。
您问道:
如果我加1,我仍然无法弄清楚这个级数的求和如何工作。请有人解释一下吗?
这个问题实际上是关于理解算法的,我想它也与SO的主题有关。但是,需要数学来描述算法为什么有效。因此,这实际上是一个数学问题。有一个关于斐波那契数列和的著名定理。如果F[i]
是第i个斐波那契数,S[n]
是前n个斐波那契数的和,则上述定理说明:
S[n] = F[n+2] - 1
因此,如果我们考虑根据
S[n+2]
的定义,
S[n+2] = S[n+1] + F[n+2]
然后,将S[n] + 1
替换为F[n+2]
:
S[n+2] = S[n+1] + S[n] + 1
你应该认识到的是你的“加1修改版”
斐波那契
函数。
以下是归纳证明,证明您的程序计算了我在原始答案中提供的总和。让
F
代表您的
斐波那契数列
函数,让
S
代表您的“加1修改版”
斐波那契数列
函数。
F[1] = 0
F[2] = 1
F[i] = F[i-1] + F[i-2] for i > 1
S[1] = 0
S[2] = 1
S[i] = S[i-1] + S[i-2] + 1 for i > 1
然后,您想要一个证明,对于
k > 0
:
k
.---
S[k] = > F[i]
`---
i = 1
请注意,仅当以下条件成立时,上述求和才是正确的:
S[1] = F[1]
S[k] = F[k] + S[k-1] for k > 1
证明相当简单。基本情况显然是真的。
S[1] = F[1] = 0
S[2] = F[2] + F[1] = 1
S[3] = S[2] + S[1] + 1 = F[3] + F[2] + F[1] = 2
归纳步骤是: 假设对于某个
k > 2
,
S[j+1] = F[j+1] + S[j]
成立于
0 < j < k+1
,证明当
j = k+1
时等式仍然成立,即:
S[k+2] = F[k+2] + S[k+1]
。
S[k+2] = S[k+1] + S[k] + 1
=> S[k+2] = (F[k+1] + S[k]) + (F[k] + S[k-1]) + 1
=> S[k+2] = (F[k+1] + F[k]) + (S[k] + S[k-1] + 1)
=> S[k+2] = F[k+2] + S[k+1]
这证明完成了。
int fib(int n){ return n <= 1 ? n : fib(--n) + fib(--n);}
吗? - user1181445