【问题标题】:Python reversing a string using recursionPython使用递归反转字符串
【发布时间】:2011-07-28 19:43:28
【问题描述】:

我想在 python 中使用递归来反转字符串,以便它向后显示字符(即“Hello”将变为“olleh”/“o l l e h”。

我写了一个迭代的方法:

def Reverse( s ):
    result = ""
    n = 0
    start = 0
    while ( s[n:] != "" ):
        while ( s[n:] != "" and s[n] != ' ' ):
            n = n + 1
            result = s[ start: n ] + " " + result
            start = n
    return result

但是我究竟如何递归地做到这一点?我对这部分感到困惑,特别是因为我不经常使用 python 和递归。

任何帮助将不胜感激。

【问题讨论】:

    标签: python string recursion


    【解决方案1】:
    def rreverse(s):
        if s == "":
            return s
        else:
            return rreverse(s[1:]) + s[0]
    

    (很少有人在 Python 语言wasn't designed for it 中进行繁重的递归处理。)

    【讨论】:

    • 好的,但底部到底是如何工作的?您正在字符串的第一个元素上调用函数 rreverse 并打印出第 0 个元素。 rreverse(s[1:]) 每次究竟是如何递增的?
    • @Eric 递归调用是从第二个元素开始对 s 的子字符串进行的(例如 S[1:] 给你的 s 没有第一个元素)。然后他将递归调用的结果附加到 s 的第一个字符,例如s[0].
    • 复杂度是多少
    • 复杂度为 O(n)
    【解决方案2】:

    要递归地解决问题,请找到一个易于解决的平凡案例,然后通过将问题分解为越来越简单的版本来找出解决该平凡案例的方法。

    你在反转字符串时要做的第一件事是什么?从字面上看,第一件事?你得到了字符串的最后一个字符,对吧?

    所以字符串的倒数是最后一个字符,后面是所有字符的倒数but最后一个字符,这就是递归的来源。字符串的最后一个字符可以写成x[-1] 而所有最后一个字符是x[:-1]

    现在,你如何“走出低谷”?也就是说,你可以在没有递归的情况下解决什么简单的情况?一个答案是一个字符串,它是相同的正向和反向。所以如果你得到一个单字符的字符串,你就完成了。

    但是空字符串更简单,有人可能实际上将它传递给你的函数,所以我们应该使用它来代替。毕竟,一个字符的字符串也可以分解为最后一个字符和除最后一个字符之外的所有字符;只是除了最后一个字符之外的所有内容都是空字符串。因此,如果我们只通过返回空字符串来处理它,我们就设置好了。

    把它们放在一起,你会得到:

    def backward(text):
        if text == "":
            return text
        else:
            return text[-1] + backward(text[:-1])
    

    或者在一行中:

    backward = lambda t: t[-1] + backward(t[:-1]) if t else t
    

    正如其他人所指出的,这不是您通常在 Python 中执行此操作的方式。迭代解决方案会更快,使用切片来完成它会更快。

    此外,Python 对堆栈大小施加了限制,并且没有尾调用优化,因此递归解决方案仅限于反转大约一千个字符的字符串。您可以增加 Python 的堆栈大小,但仍然会有一个固定的限制,而其他解决方案始终可以处理任意长度的字符串。

    【讨论】:

      【解决方案3】:

      我只是想根据Fred Foo's answer添加一些解释。 假设我们有一个名为 'abc' 的字符串,我们想要返回它的反向字符串,它应该是 'cba'。

      def reverse(s):
          if s == "":
              return s
          else:
              return reverse(s[1:]) + s[0]
         
                   
      s = "abc"
      print (reverse(s)) 
      

      这段代码的工作原理是: 当我们调用函数时

      reverse('abc')                       #s = abc
      =reverse('bc') + 'a'                 #s[1:] = bc    s[0] = a
      =reverse('c') + 'b' + 'a'            #s[1:] = c     s[0] = a
      =reverse('') + 'c' + 'b' + 'a'
      ='cba'
      

      【讨论】:

      • 为什么不是字符串索引超出范围
      【解决方案4】:

      如果这不仅仅是一个家庭作业问题,并且您实际上是为了某个更大的目标而尝试反转一个字符串,只需执行s[::-1]

      【讨论】:

      • 有趣的事实:这有时被称为“火星笑脸”。
      • reversed() 不会像您认为的那样做。 :-)
      • ^ w0w 至少解释一下
      • ^ 也许您至少应该自己尝试一下? ''.join( [i for i in reversed(s)]) 执行您认为的操作,reverseed 返回一个反转对象,您必须对其进行迭代以获取字符串。
      • 问题中明确表示他们想使用“递归”来解决问题。
      【解决方案5】:
      def reverse_string(s):
          if s: return s[-1] + reverse_string(s[0:-1])
          else: return s
      

      def reverse_string(s):
          return s[-1] + reverse_string(s[0:-1]) if s else s
      

      【讨论】:

        【解决方案6】:

        我知道现在回答原始问题为时已晚,这里已经回答了多种更好的方法。我的回答是出于文档目的,以防有人试图为字符串反转实现尾递归。

        def tail_rev(in_string,rev_string):
            if in_string=='':
                return rev_string
            else:
                rev_string+=in_string[-1]
                return tail_rev(in_string[:-1],rev_string)
            
        in_string=input("Enter String: ")
        rev_string=tail_rev(in_string,'')
        print(f"Reverse of {in_string} is {rev_string}") 
        

        【讨论】:

          【解决方案7】:
          s = input("Enter your string: ")
          
          def rev(s):
              if len(s) == 1:
                  print(s[0])
                  exit()
              else:
                  #print the last char in string
                  #end="" prints all chars in string on same line
                  print(s[-1], end="")
                  """Next line replaces whole string with same
                   string, but with 1 char less"""
                  return rev(s.replace(s, s[:-1]))
          
          rev(s)
          

          【讨论】:

            猜你喜欢
            • 2017-07-20
            • 2015-09-27
            • 2017-06-11
            • 1970-01-01
            • 1970-01-01
            • 2020-07-09
            • 2013-09-27
            相关资源
            最近更新 更多