2013-12-24 240 views
22

給定一個字符串,我想要生成所有可能的組合。換句話說,所有可能的方式都是在字符串的某個位置放置一個逗號。分隔字符串

例如:

input: ["abcd"] 
output: ["abcd"] 
     ["abc","d"] 
     ["ab","cd"] 
     ["ab","c","d"] 
     ["a","bc","d"] 
     ["a","b","cd"] 
     ["a","bcd"] 
     ["a","b","c","d"] 

我停留在如何產生的所有可能的列表了一下。組合只會給我一個字符串集合子集的長度,排列會給出所有可能的排序方法。

我可以在列表中僅使用一個逗號作爲遍歷切片的所有情況,但我無法使用兩個逗號分別爲「ab」,「c」,「d」和「a」 , 「b」, 「CD」

我嘗試瓦特/片:

test="abcd" 

for x in range(len(test)): 
    print test[:x],test[x:] 
+0

到迭代工具評議,哪一頁?我正在瀏覽這個http://docs.python.org/2/library/itertools。html,但也許這是不正確的搜索通過 –

+3

有2 ^(n-1)的可能性(你錯過了[['a','bc','d']'在你的例子中),因爲在每個點在字母之間,你可以分割或不分割字符串。 –

回答

15

如何是這樣的:

from itertools import combinations 

def all_splits(s): 
    for numsplits in range(len(s)): 
     for c in combinations(range(1,len(s)), numsplits): 
      split = [s[i:j] for i,j in zip((0,)+c, c+(None,))] 
      yield split 

其中:

>>> for x in all_splits("abcd"): 
...  print(x) 
...  
['abcd'] 
['a', 'bcd'] 
['ab', 'cd'] 
['abc', 'd'] 
['a', 'b', 'cd'] 
['a', 'bc', 'd'] 
['ab', 'c', 'd'] 
['a', 'b', 'c', 'd'] 
+1

+1爲什麼不能你不是簡單地「屈服」它,而不是將它存儲在「split」中? – thefourtheye

+0

@thefourtheye:只是因爲我傾向於一行一行地工作,而且我沒有意識到我當時已經夠深了。 :^)你是對的,當然,沒有必要綁定一個本地的。 – DSM

+0

對我來說這個瘋狂多少是在這一行:split = [s [i:j] for zip,((0,)+ c,c +(None,))],但我終於明白了! –

3

使用itertools:

import itertools 
input_str = "abcd" 
for k in range(1,len(input_str)): 
    for subset in itertools.combinations(range(1,len(input_str)), k): 
     s = list(input_str) 
     for i,x in enumerate(subset): s.insert(x+i, ",") 
     print "".join(s) 

給出:

a,bcd 
ab,cd 
abc,d 
a,b,cd 
a,bc,d 
ab,c,d 
a,b,c,d 

另外一個遞歸版本:

def commatoze(s,p=1): 
    if p == len(s): 
     print s 
     return 
    commatoze(s[:p] + ',' + s[p:], p + 2) 
    commatoze(s, p + 1) 

input_str = "abcd" 
commatoze(input_str) 
+0

更多選項用於生成響應上一個問題的功率集:http://stackoverflow.com/questions/1482308/whats-a-good-way-to-combinate-through-a-set –

15

您當然可以使用itertools這一點,但我覺得它更容易直接寫一個遞歸發生器:

def gen_commas(s): 
    yield s 
    for prefix_len in range(1, len(s)): 
     prefix = s[:prefix_len] 
     for tail in gen_commas(s[prefix_len:]): 
      yield prefix + "," + tail 

然後

print list(gen_commas("abcd")) 

打印

['abcd', 'a,bcd', 'a,b,cd', 'a,b,c,d', 'a,bc,d', 'ab,cd', 'ab,c,d', 'abc,d'] 

我不確定爲什麼我覺得這更容易。也許只是因爲它很容易直接做到這一點;-)

+0

現在嘗試在一個非常長的字符串..(我知道,我知道,不要拖拉超人的斗篷..) – DSM

1

你可以解決integer composition problem,並使用作曲來指導在哪裏拆分列表。使用一點動態編程就可以很容易地解決整數組合問題。

def composition(n): 
    if n == 1: 
     return [[1]] 
    comp = composition (n - 1) 
    return [x + [1] for x in comp] + [y[:-1] + [y[-1]+1] for y in comp] 

def split(lst, guide): 
    ret = [] 
    total = 0 
    for g in guide: 
     ret.append(lst[total:total+g]) 
     total += g 
    return ret 

lst = list('abcd') 
for guide in composition(len(lst)): 
    print split(lst, guide) 

另一種方式來產生整數組成:

from itertools import groupby 
def composition(n): 
    for i in xrange(2**(n-1)): 
     yield [len(list(group)) for _, group in groupby('{0:0{1}b}'.format(i, n))]