【问题标题】:How do I use python recursion in this scenario?在这种情况下如何使用 python 递归?
【发布时间】:2023-03-29 13:00:01
【问题描述】:

“编写一个名为 anagram(s) 的递归函数,它返回字符串 s 中所有可能的 anagram 的列表。”我可以就如何解决这个问题获得一些指导吗?我是递归新手,不明白如何为这种情况制作一个更简单的基本案例。或者我的一般算法是什么。

【问题讨论】:

  • 这能回答你的问题吗? all anagrams - recursion
  • @DanielBeck 你能用python解释一下这个概念吗?
  • 更好的是:我用英语解释了它:)

标签: list recursion combinatorics anagram permute


【解决方案1】:

我在上面的 cmets 中链接了一个重复的问题,其中包含此问题的实现,但由于这显然是一项类似于家庭作业的任务,我鼓励您将其用作最后的手段。

您的最终目标是列出给定字符串中所有可能的字母组合。

在寻找递归方法时,您需要考虑“我如何才能将这项任务分解为一遍又一遍地做同样的事情,以应对越来越简单的输入版本。”

因此,不要尝试对完整的字符串 ABCD 进行字谜,而是从第一个字母开始:你会得到一组以“A”开头的结果(并且在它之后有“BCD”的所有组合) , 一个以“B”开头(后面是“ACD”的所有组合),以此类推 C 和 D。

这是递归的第一层;一个接一个地取出每个字母作为第一个字符,然后递归字符串的其余部分。

下一层的第一个实例只需要处理三个字符串“BCD”——你知道所有这些都以“A”开头,你需要递归“B”、“C” ",第二个字母为 "D",其余字母留待洗牌。

更深一层,您从(例如)“AB”开始,并且需要针对“CD”的可能顺序进行递归。

递归的底层将是只剩下一个字母,因此没有任何东西可以洗牌;此时,您可以将其附加到前面的字符并返回结果以添加到您的字谜列表中。

您的递归函数将采用两个参数:第一个是“我已经洗牌的字母”,第二个是“我还没有洗牌的字母”。

【讨论】:

    【解决方案2】:

    组合学

    我们可以使用inductive reasoningpermutations(t) -

    1. 如果输入 t 为空,则返回空结果
    2. (归纳)t至少一个 元素。对于子问题t[1:]的所有p,对于第一个元素t[0]的所有r旋转通过p,产量r
    def permutations(t):
      if not t:
        yield ()                          #1
      else:
        for p in permutations(t[1:]):     #2
          for r in rotations(p, t[0]):
            yield r
    

    rotations((a,b,c), X) 的意思是 X 将“旋转”通过 (a, b, c) 中的每个位置 -

    (X, a, b, c)
    (a, X, b, c)
    (a, b, X, c)
    (a, b, c, X)
    

    rotations(t,e) 定义为 -

    1. 如果输入t 为空,则产生空旋转,(e)
    2. (归纳)t至少一个 元素。 yield (e, *t) 和子问题 t[1:] 的所有 r,将第一个元素 t[0] 添加到 r 和 yield
    def rotations(t, e):
      if not t:
        yield (e)                       # 1
      else:
        yield (e, *t)                   # 2
        for r in rotations(t[1:], e):
          yield (t[0], *r)
    
    for p in permutations("same"):
      print(p)
    
    ('s', 'a', 'm', 'e')
    ('a', 's', 'm', 'e')
    ('a', 'm', 's', 'e')
    ('a', 'm', 'e', 's')
    ('s', 'm', 'a', 'e')
    ('m', 's', 'a', 'e')
    ('m', 'a', 's', 'e')
    ('m', 'a', 'e', 's')
    ('s', 'm', 'e', 'a')
    ('m', 's', 'e', 'a')
    ('m', 'e', 's', 'a')
    ('m', 'e', 'a', 's')
    ('s', 'a', 'e', 'm')
    ('a', 's', 'e', 'm')
    ('a', 'e', 's', 'm')
    ('a', 'e', 'm', 's')
    ('s', 'e', 'a', 'm')
    ('e', 's', 'a', 'm')
    ('e', 'a', 's', 'm')
    ('e', 'a', 'm', 's')
    ('s', 'e', 'm', 'a')
    ('e', 's', 'm', 'a')
    ('e', 'm', 's', 'a')
    ('e', 'm', 'a', 's')
    

    字谜

    现在anagrams 可以是一个简单的join 得到的排列 -

    def anagrams(s):
      for p in permutations(s):
        yield "".join(p)
    
    for a in anagrams("same"):
      print(a)
    
    same
    asme
    amse
    ames
    smae
    msae
    mase
    maes
    smea
    msea
    mesa
    meas
    saem
    asem
    aesm
    aems
    seam
    esam
    easm
    eams
    sema
    esma
    emsa
    emas
    

    有效字词

    如果您只想找到有效的单词,您需要一个 dictionary 并在 yield 语句之前添加一个条件 -

    def anagrams(s, dictionary):
      for p in permutations(s):
        word = "".join(p)
        if word in dictionary:
          yield word
    
    mydict = {"valid", "words", "go", "here", ..., }
    
    for a in anagrams("same"):
      print(a)
    
    same
    maes
    mesa
    seam
    

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-01-05
      • 1970-01-01
      • 2022-01-23
      • 2015-11-30
      • 2017-05-16
      • 2012-10-06
      相关资源
      最近更新 更多