这看起来类似于斐波那契数列问题,并且以迭代方式实现并非易事。它也看起来像家庭作业,所以我将发布获得斐波那契迭代的步骤,您应该能够将其应用于您的问题。
如果你不知道,斐波那契是这样定义的:
def fib(n):
if n <= 1: # technically, this is not 100% correct, but it's fine for n>=0
return n
return fib(n-1) + fib(n-2)
那么我们来分析fib(n)。首先我们看到有两种不同的情况:n <= 1 和not n <= 1。对于n <= 1,fib(n) 没有依赖关系,所以我们可以评估一下:
def fib_iter(n):
if n <= 1:
return n
现在我们需要讨论另一种情况。我们先来做一个依赖分析。 fib(n) 和 n > 1 需要什么?我们致电fib(n-1) 和fib(n-2)。在迭代语言中,这将是之前的两个值。很明显,我们需要跟踪这些。我们将从关于那个的两个琐碎案例开始:
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
我希望这很明显。然后我们按照它们在递归方法中解析的顺序解析这些函数。在展开递归并分析函数时,我们发现要评估的第一个非平凡值当然是fib(2)。然后fib(3) 等等,直到我们到达n。由于递归方法,多个值被多次评估,但我们不需要在迭代方法中。将这些值相加,得到以下代码:
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
for i in xrange(2, n+1):
curr = prev1 + prev2 # calculate fib(i)
prev1, prev2 = prev2, curr # shift previous value cache
唯一缺少的是返回值,即循环结束时的curr。正如我们执行xrange(2, n+1) 并提前检查n <= 1 一样,循环将至少运行一次,因此curr 将在循环之外定义。
def fib_iter(n):
if n <= 1:
return n
prev1, prev2 = 0, 1
for i in xrange(2, n+1):
curr = prev1 + prev2
prev1, prev2 = prev2, curr
return curr
(这是我的第一个家庭作业答案;SO 社区可能会给我反馈,如果我宠坏了我可以做得更好)