目标:我试图找到一个列表的最大长度,该列表包含长度为N的非字谜,每个字谜单词由3个字母组成:“a”、“B”或“C”
例如,如果N=5:[aaaaaaa,AAAAB,…,AABBC,…,BABAA,…,CCCCC]
为了澄清,因为aab是AABAA的一个字谜,反之亦然,所以它们从输出列表中被打折
我的问题:首先,我想知道如何生成所有3^5排列。 我的尝试:
import itertools
print([''.join(p) for p in itertools.combinations_with_replacement('abc', 3)])
>> ['aaaaa', 'aaaab', 'aaaac', 'aaabb', 'aaabc', 'aaacc', 'aabbb', 'aabbc', 'aabcc', 'aaccc', 'abbbb', 'abbbc', 'abbcc', 'abccc', 'acccc', 'bbbbb', 'bbbbc', 'bbbcc', 'bbccc', 'bcccc', 'ccccc']
显然,这份名单还有很长的路要走
我考虑过分区,例如)0As,2Bs,3Cs是0+2+3。在本例中,用手进行的详尽查找在一分钟内给出了21的答案。事实上,我简化了这个过程,注意到第三个字母的数量(比如说C,不失去一般性)取决于As和Bs的组合,所以我画了一个表格——红十字代表无效的组合,因为sum>;=5:(顺便说一句,我想知道这个想法是如何延伸到N>;3的;因为从桌子上看,正方形被切成两半……)
为了将这个“算法”转移到计算机上,我曾想过以某种方式利用对称性——这让我想起了格雷码——但我无法正确地实现它
是否有任何功能可以有效地处理此问题?然后,我甚至不必(至少明确地)首先调用一个字谜检查器函数来比较输入
考虑到这个目标,生成所有
3 ** 5
可能的字符串然后过滤掉字谜的方法是无效的。可以直接计算所需的数字,而无需实际生成任何字符串:ABCAB
是AABBC
的一个字谜,因为两个字符串的字母频率都是{'A': 2, 'B': 2, 'C': 1}
李>'A', 'B', 'C'
,值为非负整数,值之和为5(因此字符串长度为5)李>n
划分为k
个部分的方法的数量来计算,其中部分的顺序很重要,并且一个部分允许为0李>下面是一个递归解决方案:
例如:
这与
itertools.combinations_with_replacement
一致,它在本例中生成了一个包含21个字符串的列表,并且与手工计算一致事实上,我们可以通过稍微不同的方式来进一步构建问题:将
n
划分为k
部分的方法的数量相当于在n
项之间插入k - 1
分隔符的方法的数量。放置分隔符的结果是长度为n + k - 1
的字符串:AA|BB|C
李>..|..|.
,那么我们可以用字母填充以生成字符串AA|BB|C
李>因此,我们可以将问题简化为计算在长度为
n + k - 1
的字符串中放置k - 1
符号|
的方法的数量。这就是二项式系数binom(n + k - 1, k - 1)
:相关问题 更多 >
编程相关推荐