获得每个字符串组合

时间:2009-09-22 02:09:26

标签: python string combinatorics

我有一个组合学分配,涉及从特定的字符串组合中获取长度小于或等于6的每个单词。

在这种情况下,它是S = {'a','ab','ba'}。教授刚开始将它们列出来,但我认为通过一个程序可以更容易地解决它。唯一的问题是我无法获得实际计算每个可能选项的好算法。

如果有人可以提供帮助,我会很感激。我通常用Python编程,但实际上我只需要帮助算法。

4 个答案:

答案 0 :(得分:9)

假设你的意思是组合(没有重复,顺序无关紧要):

import itertools

S = [ 'a', 'ab', 'ba' ]

for i in range(len(S)+1):
  for c in itertools.combinations(S, i):
    cc = ''.join(c)
    if len(cc) <= 6:
      print c

发出所有可能性:

()
('a',)
('ab',)
('ba',)
('a', 'ab')
('a', 'ba')
('ab', 'ba')
('a', 'ab', 'ba')

如果你的意思不同于“组合”,那只是在for中使用正确的迭代器或生成器的问题(例如itertools.permutations,或者你自己设计的其他东西)。< / p>

修改:例如,如果您的意思是“重复和订单非常重要”,

def reps(seq, n):
  return itertools.product(*[seq]*n)

for i in range(7):
  for c in reps(S, i):
    cc = ''.join(c)
    if len(cc) <= 6:
      print c

将为您提供所需的85行输出。

再次编辑:我的循环限制错误(因此错误的输出长度) - tx指向该指出的评论者。而且,这种方法可以产生一个字符串&gt; 1次,如果不同元组的'.join被认为是等价的;例如,它产生('a','ba')不同于('ab','a'),尽管它们的''.join是相同的(来自不同的所谓“组合”的相同“字”,我猜 - 使用中的术语不完全清楚。)

答案 1 :(得分:8)

您可以迭代生成由一部分,两部分,三部分等组成的所有字符串,直到步骤中生成的所有字符串都超过六个字符。进一步的步骤只会生成更长的字符串,因此已经生成了所有可能的短字符串。如果您在每个步骤中收集这些短字符串,最终会得到一组所有可能生成的短字符串。

在Python中:

S = set(['a', 'ab', 'ba'])

collect = set()
step = set([''])
while step:
   step = set(a+b for a in step for b in S if len(a+b) <= 6)
   collect |= step

print sorted(collect)

答案 2 :(得分:3)

def combos(S,n):
    if (n <= 0): return
    for s in S:
        if len(s) <= n: yield s
        for t in combos(S,n-len(s)): yield s+t

for x in combos(["a","ab","ba"],6): print x

打印输出:

a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaab
aaaaba
aaaab
aaaaba
aaaba
aaabaa
aaab
aaaba
aaabaa
aaabab
aaabba
aaba
aabaa
aabaaa
aabaab
aababa
aab
aaba
aabaa
aabaaa
aabaab
aababa
aabab
aababa
aabba
aabbaa
aba
abaa
abaaa
abaaaa
abaaab
abaaba
abaab
abaaba
ababa
ababaa
ab
aba
abaa
abaaa
abaaaa
abaaab
abaaba
abaab
abaaba
ababa
ababaa
abab
ababa
ababaa
ababab
ababba
abba
abbaa
abbaaa
abbaab
abbaba
ba
baa
baaa
baaaa
baaaaa
baaaab
baaaba
baaab
baaaba
baaba
baabaa
baab
baaba
baabaa
baabab
baabba
baba
babaa
babaaa
babaab
bababa

答案 3 :(得分:1)

递归地做是一种方式:

cache = {}
def words_of_length(s, n=6):
    # memoise results
    if n in cache: return cache[n]

    # base cases
    if n < 0: return []
    if n == 0: return [""]

    # inductive case
    res = set()
    for x in s:
        res |= set( (x+y for y in words_of_length(s, n-len(x))) )

    # sort and memoise result
    cache[n] = sorted(res)

    # sort results
    return cache[n]

def words_no_longer_than(s, n=6):
    return sum( [words_of_length(s, i) for i in range(n+1)], [] )