【问题标题】:Double recursive call双递归调用
【发布时间】:2018-12-03 21:16:28
【问题描述】:
 def print_numbers(n, k):  
 """Print all numbers that (A) can be formed from the digits  of `n` in reverse
order and (B) are multiples of `k`.
  Args:  n (int): The number that results must use digits from. 
 k (int): The number that results must be multiples of.    
  >>> print_numbers(97531, 5) 
     135 
     15
     35"""
   def inner(n,s):
     if n == 0:
        if s % k == 0 and s > 0:
             print(s)
     else:
          inner(n // 10, s*10 + n % 10) #first
          inner(n // 10, s) #second
   inner(n,0)

我在理解递归调用的部分时遇到了一些麻烦。据我了解,在第一次到达应该给出返回值的阶段之前,不能调用第二次递归调用。但是,第一个调用的作用(在示例中): 它给出了inner(9753,1),inner(975,13),inner(97,135),inner(9,1357),inner(0,13579)

当 n 等于 0 时,s(13579) 不能被 k(5) 整除,因此它不打印任何内容。此外,通过构造函数的方式返回值是None。因此,当达到 inner(0,13579) 阶段时,第二个递归调用必须开始工作,但它会不断尝试 0 // 10 并且不会继续。

这是我的理解。你能指出我错在哪里吗?

【问题讨论】:

    标签: python recursion higher-order-functions


    【解决方案1】:

    几个问题。 首先,将递归视为堆栈的层次结构。

    但是,第一个调用的作用(在示例中):它给出 内(9753,1),内(975,13),内(97,135),内(9,1357),内(0,13579)

    这里的一个问题是第一个调用不会被锁定到只执行那一行。每个调用都会在 else 块中产生两个新调用。稍后会详细介绍。

    所以,当内部(0,13579)阶段达到第二个递归调用 必须开始工作,但它会不断尝试 0 // 10 并且不会 继续。

    这是有缺陷的。为什么此调用的“n”值必须为零?如果你还记得,这个调用的第一个实例是在一个 else 块中,它被命中 n = 97531。

    它上面的语句进入递归并不重要,因为与该语句相关的堆栈相比,这些变量和值存在于较低的堆栈中。

    更简单的方法是分别考虑每个堆栈。

    stack 1: n = 97531
    else: #n//10 = 9753
        child1 (9753,1)
        child2 (9753,0)
                stack2 - child1:
                else: #n//10 = 975
                    child11 (975,13)
                    child12 (975,1)
                stack2 - child2:
                else: #n//10 = 975
                    child21 (975, 3)
                    child22 (975, 0) #and so on.
    

    层次结构的每个级别都确定了它们的变量,并且将生成属于较低层次结构的递归函数,直到您可以说每个“分支/生成”分别达到基本情况。

    总结 您可以将其归结为堆栈的层次结构。到那时,这个函数就变得很容易消化了。
    本质上,对于大于零的每个数字,取出最后一个数字,并做出两个选择。使用最后一个数字,并丢弃最后一个数字。一遍又一遍地这样做,你最终会考虑所有可能的数字,这些数字可以通过使用或丢弃数字以相反的顺序形成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-22
      • 2020-05-28
      • 1970-01-01
      • 2021-09-07
      • 2016-03-21
      • 1970-01-01
      • 2019-10-18
      • 2011-09-16
      相关资源
      最近更新 更多