您对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 个修改”fibonacci
功能。
下面是一个归纳证明,您的程序计算了我在原始答案中提供的总和。让F
代表您的fibonacci
功能,并让S
代表您的“添加 1 个修改”fibonacci
功能。
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]
这样就完成了证明。