【问题标题】:Reversing the order颠倒顺序
【发布时间】:2021-06-10 23:23:16
【问题描述】:

我是 python 新手,对递归不太擅长,所以如果有人能帮我解决这个问题,我将不胜感激。 所以我基本上是在尝试颠倒字符串的顺序。例如,如果字符串是“It's me”,它应该返回“me It's”。虽然,我得到了一个完全相反的字符串,并且在大多数情况下我得到一个错误,说第二个函数没有定义。

def reverse_phrase(str):
    reverse_phrase_recursive(str.split())

def reverse_phrase_recursive(str):
    if len(str)==0:
        return str
    else:
        return reverse_phrase(str[1:]) + str[0]
        
print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))

【问题讨论】:

  • 你有堆栈跟踪吗?
  • 错误我得到参考:AttributeError: 'list' object has no attribute 'split'
  • 你也返回字符串而不是 str
  • 这也是故意的吗?
  • 您的reverse_phrase_recursive 需要调用reverse_phrase_recursive,而不是reverse_phraser_p 需要一个字符串,r_p_r 需要一个列表。如果您随后将reverse_phrase 更改为return ' ',.join(reverse_phrase_recursive(str.split()),它将起作用。

标签: python python-3.x string recursion


【解决方案1】:
def reverse_phrase(str):
    return ' '.join(reversed(str.split()))

【讨论】:

  • 我试过这样的东西已经买了它需要是一个递归函数
  • 我想的也差不多。 ;)
  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
【解决方案2】:

你需要调用reverse_phrase_recursive作为递归调用,否则一个列表将被传递给reverse_phrase,然后它会尝试在一个列表上调用.split(),这会抛出一个AttributeError。

另外,实际上从 reverse_phrase 返回值,并将连接到递归调用的值变成一个列表,因为您不能直接将 str 连接到一个列表。

def reverse_phrase(str):
    return " ".join(reverse_phrase_recursive(str.split()))

def reverse_phrase_recursive(str):
    if len(str)==0:
        return str
    else:
        return reverse_phrase_recursive(str[1:]) + [str[0]]
        
print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))

旁注:不要将变量命名为“str”,它会覆盖内置的str

【讨论】:

  • 仍有一些错误,我似乎可以理解导致它们的原因,例如 TypeError: can only concatenate list (not "str") to list
【解决方案3】:

这里是倒车的解决方案:

def reverse(s): 
    return ' '.join(s.split()[::-1])

s = "DO I CHOOSE YOU PIKACHU" 
reverse(s)

#Output: 

'PIKACHU YOU CHOOSE I DO'

【讨论】:

    【解决方案4】:

    这是一个无需执行整个拆分/连接过程的递归。正如我在评论中提到的那样,它的性能很昂贵。

    
    def reverse_phrase(str, reversedStr=""):
        if (len(reversedStr) == len(str)):
          return reversedStr;
    
        reversedStrLength = len(reversedStr);  
        index = len(str) - reversedStrLength - 1;
        reversedStr += str[index];
    
        return reverse_phrase(str, reversedStr);
       
            
    print(reverse_phrase("DO I CHOOSE YOU PIKACHU"));
    
    

    【讨论】:

    • 字符串连接不是二次的(并且效率低于列表)?另外,这是python,分号是不必要的,snake_case > camelCase。
    • 刚刚检查了timeit,split+join更快。拆分+加入:%timeit reverse_phrase("DO I CHOOSE YOU PIKACHU") 1.87 µs ± 72.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)。 str 连接:%timeit reverse_phrase2("DO I CHOOSE YOU PIKACHU") 8.8 µs ± 670 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    • 随着 n 接近更大的大小,它会扩展吗?例如,如果 N 的长度为 50K 个字符?
    • 实际上,如果我们使用递归,这很可能会导致堆栈溢出,除非 Python3 支持开箱即用的 TCO。
    • 还不熟悉 Python 在字符串 concat 上的方法是什么,或者它是否支持将字符串缓冲区分配为最终产品的大小?最初的方法也是使用字符串连接不是吗?
    【解决方案5】:

    这是另一种不使用连接的方法。您的 reverse_phrase() 函数使用单词列表调用递归函数。递归函数的基本情况是当列表的长度为 2 时,在这种情况下它交换两个单词。否则,它将列表的最后一个单词与所有首字母单词的递归输出交换。

    def reverse_phrase(str):
        return reverse_phrase_recursive(str.split())
    
    def reverse_phrase_recursive(l):
        if len(l) == 2:
            return l[1] + " " + l[0]
        return l[-1] + " " + reverse_phrase_recursive(l[:-1])
    
    print(reverse_phrase('this is a great recursive function'))
    #function recursive great a is this
    

    【讨论】:

      【解决方案6】:

      这是另一种不依赖内置函数.split的方式-

      def reverse_phrase(s):
        def loop(s, word, phrase):
          if not s:
            return word + " " + phrase                #1
          elif s[0] == " ":
            return loop(s[1:], "", word + " " + phrase) #2
          else:
            return loop(s[1:], word + s[0], phrase)       #3
        return loop(s, "", "")
      
      print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))
      

      评估为 -

      loop("DO I CHOOSE YOU PIKACHU", "", "")             #3
      loop("O I CHOOSE YOU PIKACHU", "D", "")             #3
      loop(" I CHOOSE YOU PIKACHU", "DO", "")           #2
      loop("I CHOOSE YOU PIKACHU", "", "DO ")             #3
      loop(" CHOOSE YOU PIKACHU", "I", "DO ")           #2
      loop("CHOOSE YOU PIKACHU", "", "I DO ")             #3
      loop("HOOSE YOU PIKACHU", "C", "I DO ")             #3
      loop("OOSE YOU PIKACHU", "CH", "I DO ")             #3
      loop("OSE YOU PIKACHU", "CHO", "I DO ")             #3
      loop("SE YOU PIKACHU", "CHOO", "I DO ")             #3
      loop("E YOU PIKACHU", "CHOOS", "I DO ")             #3
      loop(" YOU PIKACHU", "CHOOSE", "I DO ")           #2
      loop("YOU PIKACHU", "", "CHOOSE I DO ")             #3 
      loop("OU PIKACHU", "Y", "CHOOSE I DO ")             #3
      loop("U PIKACHU", "YO", "CHOOSE I DO ")             #3
      loop(" PIKACHU", "YOU", "CHOOSE I DO ")           #2
      loop("PIKACHU", "", "YOU CHOOSE I DO ")             #3
      loop("IKACHU", "P", "YOU CHOOSE I DO ")             #3
      loop("KACHU", "PI", "YOU CHOOSE I DO ")             #3
      loop("ACHU", "PIK", "YOU CHOOSE I DO ")             #3
      loop("CHU", "PIKA", "YOU CHOOSE I DO ")             #3
      loop("HU", "PIKAC", "YOU CHOOSE I DO ")             #3
      loop("U", "PIKACH", "YOU CHOOSE I DO ")             #3
      loop("", "PIKACHU", "YOU CHOOSE I DO ")         #1
      "PIKACHU YOU CHOOSE I DO "
      

      我认为重要的是不要只以一种方式思考问题。尝试不同的方式 -

      def rev(s, pos = 0):
        if pos >= len(s):
          return s                              #1
        elif s[pos] == " ":
          return rev(s[pos+1:]) + " " + s[0:pos]  #2
        else:
          return rev(s, pos + 1)                    #3
      
      print(rev("DO I CHOOSE YOU PIKACHU"))
      

      评估为 -

      rev("DO I CHOOSE YOU PIKACHU", 0)                    #3
      rev("DO I CHOOSE YOU PIKACHU", 1)                    #3
      rev("DO I CHOOSE YOU PIKACHU", 2)                  #2
      rev("I CHOOSE YOU PIKACHU", 0) + " " + "DO"          #3
      rev("I CHOOSE YOU PIKACHU", 1) + " DO"             #2
      rev("CHOOSE YOU PIKACHU", 0) + " " + "I" + " DO"     #3
      rev("CHOOSE YOU PIKACHU", 1) + " I DO"               #3
      rev("CHOOSE YOU PIKACHU", 2) + " I DO"               #3
      rev("CHOOSE YOU PIKACHU", 3) + " I DO"               #3
      rev("CHOOSE YOU PIKACHU", 4) + " I DO"               #3
      rev("CHOOSE YOU PIKACHU", 5) + " I DO"               #3
      rev("CHOOSE YOU PIKACHU", 6) + " I DO"             #2                
      rev("YOU PIKACHU", 0) + " " + "CHOOSE" + " I DO"     #3
      rev("YOU PIKACHU", 1) + " CHOOSE I DO"               #3
      rev("YOU PIKACHU", 2) + " CHOOSE I DO"               #3
      rev("PIKACHU", 0) + " " + "YOU" + " CHOOSE I DO"   #2
      rev("PIKACHU", 1) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 2) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 3) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 4) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 5) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 6) + " YOU CHOOSE I DO"               #3
      rev("PIKACHU", 7) + " YOU CHOOSE I DO"           #1
      "PIKACHU" + " YOU CHOOSE I DO"
      "PIKACHU YOU CHOOSE I DO"
      

      有无数种方式来表达程序 -

      def find(s, char, ifmatch, nomatch):
        def loop(pos):
          if pos >= len(s):
            return nomatch()
          elif s[pos] == char:
            return ifmatch(pos)
          else:
            return loop(pos+1)
        return loop(0)
      
      def cut(s, char, ifmatch, nomatch):
        return find \
          ( s
          , char
          , lambda pos: ifmatch(s[0:pos], s[pos+1:])
          , lambda: nomatch(s)
          )
      
      def rev(s):
        return cut \
          ( s
          , " "
          , lambda left, right: rev(right) + " " + left
          , lambda last: last
          )
      
      print(rev("DO I CHOOSE YOU PIKACHU"))
      

      评估为 -

      cut \
        ( "DO I CHOOSE YOU PIKACHU"s
        , " "
        , lambda left, right: rev(right) + " " + left
        , lambda last: last
        )
      
      find \
        ( "DO I CHOOSE YOU PIKACHU"
        , " "
        , lambda pos: (lambda left, right: rev(right) + " " + left)("DO I CHOOSE YOU PIKACHU"[0:pos], "DO I CHOOSE YOU PIKACHU"[pos+1:])
        , lambda: (lambda last: last)("DO I CHOOSE YOU PIKACHU")
        )
      
      loop(0)
      loop(1)
      loop(2)
      
      (lambda left, right: rev(right) + " " + left) \
        ("DO I CHOOSE YOU PIKACHU"[0:2], "DO I CHOOSE YOU PIKACHU"[2+1:])
      
      rev("I CHOOSE YOU PIKACHU") + " " + "DO"
      
      # ...
      
      "PIKACHU YOU CHOOSE I DO"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多