【问题标题】:Recursion - List of all combinations of two letters with different count constraints递归 - 具有不同计数约束的两个字母的所有组合列表
【发布时间】:2020-08-09 17:23:33
【问题描述】:

我想打印一个列表,其中包含订购两个字母的所有可能方式,例如“a”、“b”,其中每个字母必须分别包含 n、k 次。

例如,如果我们有字母'a', 'b'n=1, k=2,那么我们应该有一个这样的列表:

[
'abb',
'bab',
'bba',
]

我设法在字符串 'a'*n+'b'*k 上使用递归排列解决了这个问题,但这非常低效,当我们在 n/k 上达到 8-10 时,程序内存不足。

如何在python中使用递归(没有itertools)解决这个问题?

【问题讨论】:

  • 你试过什么代码?
  • 实际上,itertools 会比任何“纯 python”解决方案快得多。
  • @frozen 我使用的置换函数如here 所述,但使用其他博客中的其他(更快)算法不起作用
  • @OlvinR​​oght 但我仍然想用递归来做。
  • @bendaMan,这里没有使用递归的单一理由,你有吗?

标签: python recursion combinations


【解决方案1】:

因为它具有教育意义,所以我要给你一个不同的谜题 ;-) 这很容易用递归生成器来完成:

def crunch(letters, n, k):
    a, b = letters
    def inner(n, k):
        if n == 0 == k:
            yield ""
        # It starts with a or it starts with b.
        if n:
            for tail in inner(n-1, k):
                yield a + tail
        if k:
            for tail in inner(n, k-1):
                yield b + tail
    return inner(n, k)

然后,例如,

>>> list(crunch('ab', 1, 2))
['abb', 'bab', 'bba']
>>> list(crunch('ab', 2, 1))
['aab', 'aba', 'baa']
>>> list(crunch('ab', 1, 0))
['a']
>>> list(crunch('ab', 1, 1))
['ab', 'ba']
>>> list(crunch('ab', 2, 2))
['aabb', 'abab', 'abba', 'baab', 'baba', 'bbaa']

所以有一个难题:您如何重写 not 以使用生成器?在现实生活中,没有人会费心摆脱发电机。但是,在现实生活中,任何人都会使用itertools.combinations() 作为开头(由于长度为n+k,您正在选择“a”应该去的n 位置 - 或者,等效地,@ 987654326@“b”应该去的位置)。

【讨论】:

  • 非常感谢!我会尝试解决这个难题,但出于好奇,您是如何提出这个算法的(或者这只是经验带来的东西)?
  • 你能提供任何线索吗?我不能简单地将值附加到列表而不是产生它们,我该怎么办?
  • 第一个,数十年的经验;-) 第二个,n == 0 == k 案例更改为return [""]。如果之后只有一种情况,if n: 情况可能会更改为return [a + tail for tail in inner(n-1, k)]。但是有两种情况,其中一种或两种都可能适用。
猜你喜欢
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2021-01-16
相关资源
最近更新 更多