【问题标题】:Explanation for reverse_string recursive functionreverse_string 递归函数说明
【发布时间】:2015-02-17 17:57:52
【问题描述】:

无论我用 Python 可视化工具运行它多少次,我都无法弄清楚这段代码是如何工作的;有人可以告诉我以下代码的递归是如何工作的吗?

def reverse_strings(string):
    if len(string) == 0: return ''
    else: return reverse_strings(string[1:]) + string[0]

reverse_strings('hello')

我自己写的,它可以工作,但我不知道它是如何工作的。我知道返回递归的工作原理是在递归函数中运行“ello”,但我一生都无法理解它是如何向后打印东西的。

【问题讨论】:

  • 不知道怎么写的自己怎么写的?

标签: python string recursion


【解决方案1】:

它使用切片将第一个字母连接到末尾,然后将第二个字母传递给剩余的字母再次传递给递归函数。

【讨论】:

    【解决方案2】:

    第一次通话时的string[1:]ello string[0]h

    第二次递归调用string[1:] -> llostring[0] -> e

    第三个string[1:] ->lo string[0] -> l

    第四个string[1:] ->o string[0] -> l

    5th string[1:] ->"" string[0] -> o

    所以reverse_strings(string[1:]) 调用函数在字符串中递归移动,string[0] 从末尾开始连接每个字母,这就是最后返回的内容。

    下面的图表可能会有所帮助:

    【讨论】:

      【解决方案3】:

      递归的概念是您调用相同的函数,直到遇到基本情况。在您的情况下,基本情况是len(string) == 0,您向调用者返回一个空字符串,这是同一函数reverse_strings的先前版本,但具有不同的参数(通常是更“复杂”函数)。

      假设你有这个简单的字符串hi,你的函数会是这样的:

      1. 检查是否达到基本情况,如果是,则返回一个空字符串,否则转到下一条语句。由于我们没有空字符串,我们转到下一条语句。

      2. 下一条语句调用相同的函数reverse_strings,但参数与第一次运行时不同;实际上,第一次调用它时,您会执行类似reverse_strings('hi') 的操作。在else 中,您使用较小版本的字符串hi 调用该函数,请注意以下语句:return reverse_strings(string[1:]) + string[0] string[1:] 只是i。现在,基本上你有return reverse_strings('i') + string[0]。请注意,string[0]H。在这里,reverse_strings('i'),正如我上面所说,您再次调用您的函数,但使用较小版本的字符串 i

      3. 现在,我们在另一个函数调用中。评估第一条语句if len(string) == 0: return ''。这是真的吗?不,因为len(string) 仍然与0 不同。所以我们传递到下一个语句else: return reverse_strings(string[1:]) + string[0]。现在,请注意我们将再次调用相同的函数。但使用较小的字符串,在本例中为空字符串,因为 string[1:]i 是空字符串。所以我们的电话可以总结为return reverse_strings('') + i

      4. 我们现在处于reverse_strings 的另一个“简化版本”中。第一个语句被评估if len(string) == 0: return ''。这是真的吗?是的,因为请记住,我们的字符串现在是一个空字符串。现在发生的是你返回一个空字符串给调用者,也就是第3点中的函数。

      5. 现在,我们刚刚在第 3 点向调用者返回了一个空字符串,所以我们有 return '' + i'' + i 只不过是简单的i,您将在指针 3 处返回此函数的调用者,即点 2 处的函数。

      6. 1234563 @你刚回来。所以,现在你有了iH,而且你刚刚反转了字符串。

      【讨论】:

        【解决方案4】:

        要真正理解这一点,我会用一种声明性的、某种逻辑形式来表达它。 这是你的代码:

        1: if len(string) == 0: return ''
        2: else: return reverse_strings(string[1:]) + string[0]
        

        我将字符串的第一个元素 (string[0]) 称为 head,其余的 (string[1:]) 称为 tail。如果一个字符串只有 1 个字符长,我们认为它的尾部是空字符串。就该词汇而言,以下是反转字符串含义的规则:

        1. 空字符串反转为空字符串。
        2. 任何其他反转的字符串都是其尾部的反转版本,然后是其头部。

        例如,abcd,我们应用规则 2,因为规则 1 不适用:

        • abcd 反转是bcd 反转,然后是a

        好的,bcd 反转了什么?好吧,我们可以应用相同的规则:

        • bcd 反转是cd 反转,然后是b

        并沿着链条:

        • cd 反转为d 反转,后跟c
        • d 反转是'' 反转,后跟d
        • 根据规则 1,'' 反转为 '',因为它是空字符串。

        回到这个列表,你会得到:

        • '' 后跟 d 后跟 c 后跟 b 后跟 a

        这是dcba,这就是我们想要的!

        了解递归并不容易。尝试用它解决一些其他问题或做一些需要它的练习;这种做法确实有助于理解。

        【讨论】:

          猜你喜欢
          • 2014-04-06
          • 1970-01-01
          • 2016-01-16
          • 1970-01-01
          • 1970-01-01
          • 2018-08-08
          • 1970-01-01
          • 2018-04-19
          • 2011-09-04
          相关资源
          最近更新 更多