【问题标题】:Could anyone show me how the recursive part of this function works?谁能告诉我这个函数的递归部分是如何工作的?
【发布时间】:2015-01-13 14:30:39
【问题描述】:

我得到了一个递归函数的例子,我只是需要一些帮助来理解它。

我知道递归函数 a) 必须有一个基本情况,b) 必须更改参数并朝着基本情况移动,c) 必须调用自己

代码如下:

def func(x,y):
   if y == 0:
       return 0
   else:
       return x + func(x,y-1)

我只是在努力理解 func(x,y-1)。我知道函数返回 x 和 y 的乘积,但我不确定函数的递归部分是如何工作的。

【问题讨论】:

  • iF Y = 4 然后返回return x + x + x
  • 啊,看起来好简单!感谢大家。我似乎不明白为什么我们必须假设 func(x,y-1) 返回 x 和 y-1 的乘积,但现在更清楚了。

标签: python function recursion


【解决方案1】:

此函数将 x 元素添加 y 次。下面是它的工作原理:

当你用 3、2 调用你的 func 时,你执行以下操作:

  • 检查 y 是否为 0,如果为 0,则返回 0。这是从递归返回的必要条件。
  • 如果它不为零,则添加 3 + fun(3, 1) 这部分进入堆栈并再次调用函数。
  • 它再次检查 y 值并执行 3 + func(3, 0)。这部分再次入栈并再次调用函数
  • 现在是 0,所以它返回并从堆栈中弹出顶部元素,即 3 + fun(3, 0),现在由于 fun(3, 0) 返回 0,它将返回 3
  • 再次弹出我们留下的顶部元素,即 3 + fun(3, 1)。上一步中的 fun(3,1) 返回 3,因此它将 fun(3, 1) 替换为 3 并返回 3 + 3 = 6。 - 现在由于堆栈上没有任何元素(即没有更多的函数评估),它返回 6 并返回给调用者。

【讨论】:

    【解决方案2】:

    func(x,y-1) 只是用新值 x 和 y-1 再次调用 func 例如, 取 x=5, y=6 第一次调用将是:func(5,6) 之后,它会调用 func(5,5) -> func(5,4) -> func(5,3) -> func(5,2) -> func(5,1) ->函数(5,0)

    最后 func(5,0) 将返回 0 给它的调用者。 & 它会一直持续到第一次调用...

    简而言之,每次该函数重复时,它都会用 y 的少一个值(即第二个变量)调用它自己,最终它会在 y=0 时终止。

    【讨论】:

      【解决方案3】:

      我们假设func 是一个返回其两个参数的乘积的函数(假设y 是一个非负整数)。 y 为 0 时显然是正确的,因为

      if y == 0:
          return 0
      

      对于x 的任何值,x * 0 为 0。否则,它返回 x + func(x, y-1),由于我们假设 func(x, y-1) 返回 xy-1 的乘积,我们可以确认

      x + x*(y-1) = x + x*y - x
                  = x*y
      

      所以func(x, y) 确实为任何x 和任何非负整数y 返回x * y

      我的大学教授曾经告诉我们“相信你的递归”。在进行递归调用时,只需假设递归调用将在编写递归案例时返回“正确的东西”;只要您正确地使递归调用比原始调用“更简单”,它就会“正常工作”。

      【讨论】:

        【解决方案4】:

        您的函数每次都会减少y 的值,直到它得到0 然后在每次调用中你仍然是x 所以取决于y 的值你有x 的总和实际上是函数是y*x

        >>> def func(x,y):
        ...    if y == 0:
        ...        return 0
        ...    else:
        ...        return x + func(x,y-1)
        ... 
        >>> func(3,4)
        12
        >>> func(3,0)
        0
        

        例如对于func(3,4),你的函数返回这个:

         3 + func(3,3)= 3+ func(3,2) = 3 + func(3,1) = 3 + func(3,0)= 3+0
        

        如果我们替换 funcs ,我们将有:3+(3+(3+(3+0))) 等于 12

        【讨论】:

          【解决方案5】:

          正如你所说,函数一直在调用自己。如果是这样的话:

          def func(x,y):
              return func(x,y)
          

          它会无休止地调用自己,不会给你结果。

          但是,如果每次调用都使 y 变小,则可以在某个时候停止“疯狂”,例如当 y 达到零时。然后,如果 y 每次都小 1,则 func(2, 2) 会调用 func(2, 1),后者会调用 func(2, 0),后者最终会返回一个值,因为此时 y=0。 func(2, 1) 使用该值并向其添加“x”,依此类推。最后 func(2, 2) 会将 x 添加到该返回值。然后返回 x 乘以 y 函数调用或 2*2。

          【讨论】:

            【解决方案6】:

            我还应该说应该进行以下优化:if y == 0 or x == 0:,或者调用func(0, 1000) 会不必要地将值放入堆栈

            【讨论】:

              【解决方案7】:

              计算机程序的结构和解释 (SICP) 将迭代过程描述为“携带”解决问题所需的所有信息的过程,而递归过程必须“记住它来自哪里”才能解决问题问题。

              查看区别的一种方法是跟踪问题的长度如何在解决过程中增长然后缩小。

              def func(x,y):
                 if y == 0:
                     return 0
                 else:
                     return x + func(x,y-1)
              
              func(5,4)
              func(5,4) --> 5 + func(5,3)
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2)
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2) -- > 5 + func(5,1)
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2) -- > 5 + func(5,1) --> 5 + func(5,0)
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2) -- > 5 + func(5,1) --> 5 + func(5,0) --> 0
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2) -- > 5 + func(5,1) --> 5 + 0
              func(5,4) --> 5 + func(5,3) --> 5 + func(f,2) -- > 5 + 5
              func(5,4) --> 5 + func(5,3) --> 5 + 5 + 5
              func(5,4) --> 5 + 5 + 5 + 5
              5 + 5 + 5 + 5
              20
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-11-30
                • 1970-01-01
                • 1970-01-01
                • 2016-02-14
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多