我想获得长度为k的字符串中所有可能的字母组合。我知道有很多帖子,但我有一点扭曲k大于字符串的长度。
这就是我到目前为止,它的简单和工作,如果k< = len(字符串):
string = 'ABCD'
permutations = ["".join(x) for x in itertools.permutations(string, k)]
如果k = 4,则结果:
['ABCD', 'ABDC', 'ACBD', 'ACDB', 'ADBC', 'ADCB', 'BACD', 'BADC', 'BCAD', 'BCDA',
'BDAC','BDCA', 'CABD', 'CADB', 'CBAD', 'CBDA', 'CDAB', 'CDBA', 'DABC', 'DACB',
'DBAC', 'DBCA', 'DCAB', 'DCBA']
这可以按预期工作。但是,我希望这四个字母的所有可能组合与k> LEN(字符串)。
我想要的一个例子:
string = 'AB'
k = 4
result = ['AAA,'ABB','AAB', 'ABA','BBB', 'BAA'.......]
提前致谢。
答案 0 :(得分:8)
你可能想要
itertools.product(string, repeat=k)
代替。试试吧!你的描述不明确,所以无法猜测。
示例:
>>> import itertools
>>> for p in itertools.product("ab", repeat=3):
... print p
('a', 'a', 'a')
('a', 'a', 'b')
('a', 'b', 'a')
('a', 'b', 'b')
('b', 'a', 'a')
('b', 'a', 'b')
('b', 'b', 'a')
('b', 'b', 'b')
答案 1 :(得分:3)
根据您的评论:
我试图在一个非常大的字符串中搜索每个组合的出现次数,并查看最常出现的组合。
还有另一种方法可以做你想做的事:
def substrings(vlarge, k):
return (vlarge[idx:idx+k] for idx in range(len(vlarge)-k+1))
def uses_only(value, chars):
return all(ch in chars for ch in value)
def most_common(vlarge, chars, k):
return collections.Counter(s for s in substrings(vlarge, k) if uses_only(s, chars)).most_common(1)
然后你可以看看让这个基本想法更有效率:例如,如果你在'x'
中遇到vlarge
字符,那么你知道包含它的子字符串都不是{{1}的组合}}。因此,您可以跳到在'abcd'
:
x
与这种方法相比,显而易见的是&#34;想法(迭代所有组合,计算它们作为子串出现的次数,并跟踪到目前为止最好的那些)使用更少的内存但是批次更慢,因为它必须做出<通过非常大的字符串传递em> lot 。
如果我误解了你的意思&#34;组合&#34;,也就是说如果我的def generate_substrings(vlarge, chars, k):
idx = 0
goodrange = 0
while idx <= len(vlarge) - k:
while goodrange < idx + k:
if vlarge[goodrange] in chars:
goodrange += 1
else:
idx = goodrange + 1
if idx > len(vlarge) - k:
return
goodrange = idx
yield vlarge[idx:goodrange]
idx += 1
def most_common(vlarge, chars, k):
return collections.Counter(generate_substrings(vlarge, chars, k)).most_common(1)
功能不正确,那么你必须相应地调整我的想法。重点是:计算所需表单的实际子字符串,因为它们的数量少于正确形式的假设子字符串。
答案 2 :(得分:1)
我的回答只是对你正在做的事情的理论分析。 我将用 C(k,n)表示定义包含 n 元素的集合的 k 元素的部分数量的二项式系数。< / p>
假设你有一个长度 n ∈ℕ * 和 k ∈ℕ, k⩾n 的字符串。我会假设你的字符串中的所有字符都是不同的 我知道您正在尝试构建从输入字符串中提取的 k 字符串。
字符串字符的组合可以看作是⟦ 1,n per的排列。有 n!这样的排列......
然后,当 k&gt; n ,事情变得更糟......让 r = k mod n 和 p =(k - r)/ n 。显然我们有:
p⩾1
0⩽r&lt; P 的
您的输出字符串可以在 p “完整”子字符串中进行分解,这些子字符串是由 n 输入字符的排列组成的,而一个子字符串仅由组成r 输入字符串的字符。
要构建这样一个“不完整”的子字符串,首先必须选择输入字符串的 r 字符的子集,然后选择这些字符的排列。最后,这些可能的子串的数量 s r,n 是:
s r,n = C(r,n).r!
请注意,当r = 0时,此公式不会导致无效的全局结果,因为C(0,n)= 1和0!按惯例= 1。
根据您的方案可以构建的 k -long字符串的最终数量为:
s tot =(C(r,n).r!)。(n!) p
这个数字非常高!
k = 4 且 n = 2 ,我们有:
s tot =(C(0,4).0!)。(2!) 2 = 4
result = ['ABAB', 'ABBA', 'BAAB', 'BABA']