【问题标题】:n length combinations from two or more digits with repetition limit来自两个或多个数字的 n 长度组合,具有重复限制
【发布时间】:2021-02-09 05:06:28
【问题描述】:

我有字母 a 和 b,我想从中提取 n 个长度组合,其中 a 和 b 有重复限制。

例如,如果 n = 7、a = 4 和 b = 3,则可能期望的结果以“b”开头:

bbbaaaa
bbabaaa
bbaabaa
bbaaaba
bbaaaab
babbaaa
bababaa
babaaba
babaaab
baabbaa
baababa
baabaab
baaabba
baaabab
baaaabb

我研究了很多 python 和 c 函数,但没有一个完全符合我的要求,我不知道如何更改/使用它们来这样做。

我最初的想法是存储所有可能的组合,然后在其中 a=(length) 处选择它们。但是,这很容易遇到内存问题...... 谢谢

【问题讨论】:

  • 为什么没有样本以a开头?有什么特别的原因吗?
  • 这是可以使用itertools.combinations() 的东西吗?
  • @Chris 从给定列表中寻找以特定字母开头的组合。问题已编辑。谢谢
  • @summea 不成功,正在寻找一些建议

标签: python combinations


【解决方案1】:

在字符串 'aaaabbb' 上使用 itertools.permutations()。这不是“高效”的,您需要删除重复项。

from itertools import permutations

for l in set(permutations('a'*4 + 'b'*3, 7)):
    print(*l, sep='')
babbaaa
abaabba
bbaaaab
aaabbba
ababaab
abaaabb
baaaabb
babaaba
aababba
baaabba
aabbaab
abbbaaa
abbaaba
baababa
bababaa
aabaabb
aaabbab
abaabab
bbabaaa
baaabab
aaaabbb
aabbbaa
bbbaaaa
baabbaa
babaaab
aababab
abbabaa
bbaaaba
abababa
baabaab
aaababb
abbaaab
bbaabaa
ababbaa
aabbaba

泛化为函数:

from itertools import permutations

def f(**kwargs):
    population = ''.join(s*n for s,n in kwargs.items())
    return (''.join(l) for l in set(permutations(population, len(population))))

>>> f(a=3, b=4)
<generator object f.<locals>.<genexpr> at 0x7fc1ec51fd60>

>>> list(f(a=3, b=4))
['aabbabb', 'bbaaabb', 'bbbbaaa', 'aaabbbb', 'bbbaaab', 'abaabbb', 'bbbaaba', 'baabbab', 'babbaab', 'bbabbaa', 'babaabb', 'babbaba', 'baaabbb', 'aabbbab', 'aabbbba', 'baabbba', 'bbaabab', 'baababb', 'bbabaab', 'aababbb', 'abbbbaa', 'bbaabba', 'bbababa', 'abbabab', 'abababb', 'bababab', 'abbabba', 'bababba', 'abbbaab', 'abbbaba', 'abbaabb', 'babbbaa', 'bbbabaa', 'ababbab', 'ababbba']
>>> print(*(f(a=3, b=4)))
aabbabb bbaaabb bbbbaaa aaabbbb bbbaaab abaabbb bbbaaba baabbab babbaab bbabbaa babaabb babbaba baaabbb aabbbab aabbbba baabbba bbaabab baababb bbabaab aababbb abbbbaa bbaabba bbababa abbabab abababb bababab abbabba bababba abbbaab abbbaba abbaabb babbbaa bbbabaa ababbab ababbba

>>> list(f(a=1,b=1,c=1))
['cab', 'bac', 'abc', 'acb', 'bca', 'cba']

【讨论】:

  • 谢谢你的回答,这里我们只能打印以'b'开头的组合吗?
  • 删除bs 之一并计算没有它的排列。然后在前面加一个b back tp
  • 另外,可能还有更好的方法......随着尺寸的增加,这个方法很快就会变得太慢。为此,您或许应该取消对这个答案的接受,以鼓励其他答案。如果没有更好的结果,您可以稍后接受。
【解决方案2】:

您正在寻找排列,而不是组合。然后你把它作为一个集合来消除相同的排列。

import itertools as it

def find_combos(n,a,b):
    lst = ["a"]*a + ["b"]*b
    return set(it.permutations(lst))

for p in find_combos(7,4,3):
    print(p)

【讨论】:

    【解决方案3】:

    我相信您最有效的方法是使用 range() 中的组合值作为插入新字符的位置值。另外,利用递归函数,我相信我们可以编写一个函数来适应任何大小的字母表。

    from itertools import combinations
    
    letters = 'abcdefghijklmnop'
    def combos(*sizes,level=[]):
        a = sum(sizes[len(level):])
        b = sizes[len(level)]
        if a!=b:
            for i in combinations(range(a),b):
                for r in f(*sizes, level=level + [i]):
                    yield r
        else:
            r = [letters[len(sizes)-1]]*sizes[-1]
            for l,c in reversed(list(zip(level,letters))):
                for i in l:
                    r.insert(i,c)
            yield ''.join(r)
    
    print(list(combos(3,4)))
    print(list(combos(2,2)))
    print(list(combos(2,1,2)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多