python中字符串的所有可能长度k组合

时间:2013-10-17 21:02:43

标签: python string algorithm

我想获得长度为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'.......]

提前致谢。

3 个答案:

答案 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']