【问题标题】:How would I write this recursive function iteratively?我将如何迭代地编写这个递归函数?
【发布时间】:2012-07-01 05:12:45
【问题描述】:

在 Python 中:

def g(n):  
    if n <=3:        
        return n   
    return g(n-1) + 2 * g(n-2) + 3 * g(n-3)

我明白这个函数在做什么,但我似乎不知道如何让它迭代。请帮忙。如果可能,请附上解释,以便我能完全理解问题。

【问题讨论】:

  • 家庭作业? n的最大值是多少?
  • 嗯,你知道如何计算前三个,对吧?以及如何根据前三个计算任何后续数字?
  • 也许我有点困惑,因为它是纯文本的,但是您有两个彼此相邻的 return 语句。你能更好地格式化这个吗?很难理解
  • 没有最大值。我刚刚重新格式化了 Ryan,抱歉。
  • 这是正确的。迭代函数很容易定义,因为该函数使用求和。

标签: python function recursion iteration


【解决方案1】:

这看起来类似于斐波那契数列问题,并且以迭代方式实现并非易事。它也看起来像家庭作业,所以我将发布获得斐波那契迭代的步骤,您应该能够将其应用于您的问题。

如果你不知道,斐波那契是这样定义的:

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 &lt;= 1not n &lt;= 1。对于n &lt;= 1fib(n) 没有依赖关系,所以我们可以评估一下:

def fib_iter(n):
    if n <= 1:
        return n

现在我们需要讨论另一种情况。我们先来做一个依赖分析。 fib(n)n &gt; 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 &lt;= 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 社区可能会给我反馈,如果我宠坏了我可以做得更好)

【讨论】:

    【解决方案2】:
    def g(n):
        if n <= 3:
            return n
        a, b, c = 1, 2, 3
        for i in range(3, n):
            a, b, c = b, c, (a * 3 + b * 2 + c)
        return c
    

    【讨论】:

      【解决方案3】:

      你的递归函数可以读作

      To find the value of g(30), find the value of g(29), g(28), and g(27)
        To find the value of g(29), find the value of g(28), g(27), and g(26)
          To find the value of g(28), find the value of g(27), g(26), and g(25)
            ...
              (repeat until all sub-finds have completed)
      

      一个迭代函数将从另一端开始,

      I know the values of g(1), g(2), and g(3) -> calculate g(4)
      I know the values of g(2), g(3), and g(4) -> calculate g(5)
      I know the values of g(3), g(4), and g(5) -> calculate g(6)
      ...
      (repeat until the desired g(n) is reached)
      

      【讨论】:

        【解决方案4】:

        这太有趣了,不解决......

        def g(n, *, _cache=[0, 1, 2, 3]):
            for _ in range(n - len(_cache) + 1):
                _cache.append(sum(i * _cache[-i] for i in (1, 2, 3)))
            return _cache[n]
        

        希望您已经找到了解决方案。

        【讨论】:

        • 这证明应该有一个混淆python竞赛。
        • 可能被混淆了,但由于缓存的使用,该功能也非常高效。
        • 真的没有冒犯,我喜欢 ;)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-19
        • 2021-11-16
        • 2016-09-22
        • 2016-08-13
        • 1970-01-01
        • 2021-06-08
        • 2023-03-20
        相关资源
        最近更新 更多