reverse_string递归函数的解释

时间:2014-12-18 20:32:03

标签: python string recursion

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

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

reverse_strings('hello')

我自己写了,它有效,但我不知道它是如何工作的。我知道返回递归是通过运行" ello"进入递归函数,但我不能理解它是如何向后打印的。

4 个答案:

答案 0 :(得分:1)

递归的概念是你在遇到基本情况之前调用相同的函数。在您的情况下,基本情况是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:]的{​​{1}}是一个空字符串。因此,我们的通话可以概括为i

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

  5. 现在,我们刚刚在第3点向调用者返回一个空字符串,因此我们有if len(string) == 0: return ''return '' + i只不过是简单'' + i,你将在指针3处返回此函数的调用者,这是第2点的函数。

  6. 现在,您刚刚向调用方返回了i,特别是您刚刚将i返回到此语句i,其中return reverse_strings('i') + string[0]为{{1}您刚刚返回的string[0]H只是reverse_strings('i')。所以,现在你有i,你刚刚颠倒了字符串。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

第一次通话中的

string[1:] ello string[0]h

第二次递归通话string[1:] -> llo string[0] -> e

第3 string[1:] ->string[0] -> l

第4 string[1:] -> o string[0] -> l

第五string[1:] ->“”string[0] -> o

所以reverse_strings(string[1:])调用函数递归移过字符串,string[0]连接从结尾开始的每个字母,这是最后返回的结果。

下图可能有所帮助:

recursion tree

答案 3 :(得分:0)

要真正理解这一点,我会以声明的,逻辑的形式表达它。 这是您的代码:

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

我会调用字符串的第一个元素(string[0]),其 head ,其余部分(string[1:])调用 tail 。如果一个字符串只有1个字符长,我们认为它的尾部是空字符串。就这个词汇而言,这里是反转字符串意义的规则:

  1. 空字符串反转是空字符串。
  2. 任何其他反转的字符串是其尾部的反转版本,其后是其头部。
  3. 如果是abcd,我们会应用规则2,因为规则1不适用:

    • abcd撤消bcd撤消,然后a

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

    • bcd撤消cd撤消,然后b

    并向下链:

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

    回到这个列表,你得到:

    • ''后跟d,然后是c,然后是b,后跟a

    dcba,这就是我们想要的!

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