【问题标题】:Why is my recursive function won't work and why do I get strange results为什么我的递归函数不起作用,为什么我会得到奇怪的结果
【发布时间】:2020-09-21 04:00:29
【问题描述】:

我需要编写一个代码,该代码将采用一串数字并找到连续的 5 位数字,这将为我提供可能的最高数字(如 9328498503734,答案将是 9850374)。

x = 0    
def solution(digits):
    global x 
    if len(digits) < 5:
        return x
    else:
        if int(digits[0:5]) > x:
            x = int(digits[0:5])
        solution(digits[1:])

我的想法是使用递归函数 - 检查输入的长度是否不小于 5,如果不是,则检查当前 5 位是否为最大数字。如果是这样,这个数字就变成了新的 x,并且函数被重复,但没有第一个数字,直到基本情况被遗漏。

所以我的第一个问题是如何在没有全局变量的情况下执行此操作?我听说它们被避开了,但是当我编写以前的递归代码并在该函数中使用任何变量时,它每次都会被重置。

我的下一个问题是,这个函数返回 None,我不知道为什么?另外,当我尝试在每次递归的全局 x 上放置“print (len(digit))”时,我可以看到发生了什么!它没有返回“无”,而是引发"RuntimeError: maximum recursion depth exceeded while calling a Python object",我不知道为什么?虽然,没有这个计数器,我有 None 作为回报。

那么,如何在没有全局变量的情况下执行此操作?为什么我的代码会通过简单的打印语句改变它的行为?
您的帮助将不胜感激!

编辑:好的,我得到了无,因为我试图从函数内部调用函数,但我忘记了它必须用“return”调用,而不是像那样,就像我会在函数之外那样做。

非常感谢下面的用户告诉我,我可以通过将此变量放在函数括号中来在函数中携带 ariable。我绝对不会推荐 Codecademy,因为它忽略了如此简单和重要的东西,只提供了非常基本和不完整的主题知识。我完成了他们的 Python 课程,所有练习,这就是我在这之后所知道的:/

【问题讨论】:

  • return solution(digits[1:])....而且你的代码还是有一些错误。
  • "连续 5 位数字"..."9328498503734 答案将是 9850374" 那是 7 位数字。您是说 98503 吗?
  • 好的,现在当你指向它时,我想我看到了,每次迭代都会使用相同的字符串。所以我不知道该怎么做,我尝试了 digits.replace(digits[0], "") solution(digits) 但是当我添加计数器时,它表明我输入的每个递归长度都是相同的,就像 replace 没有'根本不工作:(百分百,是的

标签: python recursion


【解决方案1】:

在调用函数时传递x 'along' 而不是使用全局变量。通过将其设置为默认值0,它不需要在开始时传入:

def solution(digits, x=0):
    if len(digits) < 5:
        return x
    else:
        if int(digits[0:5]) > x:
            x = int(digits[0:5])
        return solution(digits[1:], x)

print(solution('9328498503734'))
98503

【讨论】:

  • 天哪,这太简单了,太棒了,我希望他们在 Codecademy 上构思它,而不是像这样给我充满漏洞的知识。
【解决方案2】:

通常要使递归函数工作,您需要return 某种基本结果与对原始参数的简化版本的另一个递归调用的结果的某种组合。使用全局变量通常会弄巧成拙,因为所有递归调用都会相互覆盖(使用全局变量是“避免”的原因,因为它通常使您的代码无法工作,哈哈)。

>>> def solution(digits: str) -> str:
...     """Returns the 5-digit substring of digits with the highest int value."""
...     if len(digits) <= 5:
...         return digits
...     else:
...         return max(digits[:5], solution(digits[1:]), key=int)
...
>>> solution("9328498503734")
'98503'

【讨论】:

  • 什么是基本结果?
  • “基本情况”是超级简单的一种,输入非常简单,无需进一步递归,答案就很明显。在这个例子中,它是len(digits) &lt;= 5 的情况——如果只有 5 个数字,那么它们只有一个可能的子集,所以你可以直接返回。其他所有解决方案都只是前 5 位数字的 max 和第一个数字之后的所有数字的 solution(即最终会到达基本情况的稍短的数字字符串)。
  • 哦,我不知道基本情况和基本结果是一样的
  • 等等,如果我执行 len(digits)
  • 不,因为您是 returning 数字,因此呼叫者将使用 max 将它们与前 5 位数字进行比较。 (然后该调用者将返回该最大值,然后 its 调用者将进行另一次比较,然后继续进行。)这就是为什么返回而不是使用全局变量是关键;函数的每次调用都将返回一个可能不同的结果,您需要能够将两个结果作为不同的值进行比较!如果所有内容都存储在同一个全局中,则很难做到这一点。
【解决方案3】:
def max_5_digits(digits, _max=0):
    return _max if len(digits) < 5 else max_5_digits(digits[1:], max(_max, int(digits[:5])))
max_5_digits("9328498503734")                                                                                                                                                                           
## 98503

【讨论】:

  • 这不是在回答任何问题,这只是直接给我解决方案,与我正在寻找的不同。谢谢,但我想学习。
  • @JanKowalski 唯一的诀窍是:A if cond1 else B - python 中的单行 if-else。另一个技巧是:max() 保存一个 if-else 条件。
  • @JanKowalski 啊,你通过使用可选参数`_max`保存全局变量,它在函数调用上“结转”关于_max值的内存。同时这个函数满足函数式编程的标准(引用透明):(相同的参数输入应该总是给出相同的输出)。
猜你喜欢
  • 1970-01-01
  • 2013-05-12
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 2021-12-22
相关资源
最近更新 更多