具有替换和最大出现约束的组合

Combinations with Replacement and maximal Occurrence Constraint

from itertools import *
import collections
for i in combinations_with_replacement(['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'],15):
    b = (''.join(i))
    freq = collections.Counter(b)
    for k in freq:
        if freq [k] < 5:
            print(k)

此代码最多打印字符,如果小于 5 个则算作什么

我尝试做的是,如果在该字符串的任何位置重复了小于 x 次的任何字符,并仅打印符合该条件的字符串。

问题不在于我尝试做什么,或其全部打印并忽略 if ... 或打印 notting。 如何做对,或者可能在 python 存在简单的解决方案?

结果最多以小于5为例

False - fffaaffbbdd ( repeat 5 titemes f)
False - fffffaaaaac ( repeat 5 times a and f)
True -  aaabbbccc11 ( no any character repeated more than 4 times )

更清楚地解释问题 - 在提供给下一个函数之前过滤所有字符重复次数超过 x 的字符串。 例如 - 有简单的 print that strings ,而不是 print strings what not at rule.

如果我没理解错的话,您想打印每个字符最多只出现 4 次的字符串:

from collections import Counter
from itertools import combinations_with_replacement


for i in combinations_with_replacement(['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'],15):
    c = Counter(i)
    if c.most_common(1)[0][1] > 4:
        continue
    print(''.join(i))

打印:

...

00002446899cccd
00002446899ccce
00002446899cccf
00002446899ccdd

... 

一种更具建设性的方法(意思是:我不会遍历所有可能的组合 - 我直接构建有效组合)。

您需要安装 sympy 才能运行。

在这个例子中我只使用了元素 "abcdef" 并且限制重复次数严格小于 MAX = 4。我将要输出的字符串的长度固定在 M = 6.

我首先获取 M 的所有 partitions,重复次数有限 k=MAX - 1,并且不超过 m=N 个部分。我立即将它们转换为列表:

{3: 2} [3, 3, 0, 0, 0, 0]
{3: 1, 2: 1, 1: 1} [3, 2, 1, 0, 0, 0]
{3: 1, 1: 3} [3, 1, 1, 1, 0, 0]
{2: 3} [2, 2, 2, 0, 0, 0]
{2: 2, 1: 2} [2, 2, 1, 1, 0, 0]
{2: 1, 1: 4} [2, 1, 1, 1, 1, 0]
{1: 6} [1, 1, 1, 1, 1, 1]

在这些列表中,我迭代了多重排列 - 我的意思是那些代表我 select 的元素以及它们重复的频率:例如:

[2, 1, 2, 0, 0, 1] -> "aabccf"  # 2*"a", 1*"b", ..., 0*"e", 1*"f"

你想要的结果就是这些字符串的多重排列。

from sympy.utilities.iterables import multiset_permutations, partitions

MAX = 4  # (all counts < MAX)
elements = "abcdef"
N = len(elements)
M = 6  # output length


def dict_to_list(dct, N):
    ret = [0] * N
    j = 0
    for k, v in dct.items():
        ret[j:j + v] = [k] * v
        j += v
    return ret


for dct in partitions(M, k=MAX - 1, m=N):
    lst = dict_to_list(dct, N)
    for part in multiset_permutations(lst):
        el = ''.join(n * v for n, v in zip(part, elements))
        for msp in multiset_permutations(el):
            print(''.join(msp))

对于您的情况,您需要更改:

MAX = 5  # (all counts < MAX)
elements = "0123456789abcdef"
M = 15  # output length

但它的复杂性很大(但比最初的方法好得多)!