2013-05-10 49 views
6

Làm cách nào để tạo tất cả các kết hợp có thể có của một chuỗi có khoảng cách giữa các ký tự?Làm cách nào để tạo tất cả các kết hợp có thể có của một chuỗi có dấu cách giữa các ký tự? Python

[in]: "foobar" 

[out]: 
['foobar', 'f oobar', 'fo obar', 'f o obar', 'foo bar', 'f oo bar', 'fo o bar', 
'f o o bar', 'foob ar', 'f oob ar', 'fo ob ar', 'f o ob ar', 'foo b ar', 
'f oo b ar', 'fo o b ar', 'f o o b ar', 'fooba r', 'f ooba r', 'fo oba r', 
'f o oba r', 'foo ba r', 'f oo ba r', 'fo o ba r', 'f o o ba r', 'foob a r', 
'f oob a r', 'fo ob a r', 'f o ob a r', 'foo b a r', 'f oo b a r', 'fo o b a r', 
'f o o b a r', 'foobar', 'f oobar', 'fo obar', 'f o obar', 'foo bar', 
'f oo bar', 'fo o bar', 'f o o bar', 'foob ar', 'f oob ar', 'fo ob ar', 
'f o ob ar', 'foo b ar', 'f oo b ar', 'fo o b ar', 'f o o b ar', 'fooba r', 
'f ooba r', 'fo oba r', 'f o oba r', 'foo ba r', 'f oo ba r', 'fo o ba r', 
'f o o ba r', 'foob a r', 'f oob a r', 'fo ob a r', 'f o ob a r', 'foo b a r', 
'f oo b a r', 'fo o b a r', 'f o o b a r'] 
+0

Gợi ý: bạn có thể xem xét việc tách một chuỗi ở mỗi vị trí, và sau đó đệ quy làm tương tự cho mỗi chuỗi –

+2

Tại sao bạn đã thay đổi sản lượng của bạn quá nhiều? – jamylak

Trả lời

3
import itertools as it 

def func(s): 
    if not s: 
     return [s] 
    binary = it.product(['',' '], repeat=len(s)-1) 
    zipped = (it.izip_longest(s , comb, fillvalue='') for comb in binary) 
    return [''.join(it.chain.from_iterable(x)) for x in zipped] 

func('foobar') 

đầu ra:

['foobar', 
'fooba r', 
'foob ar', 
'foob a r', 
'foo bar', 
'foo ba r', 
'foo b ar', 
'foo b a r', 
'fo obar', 
'fo oba r', 
'fo ob ar', 
'fo ob a r', 
'fo o bar', 
'fo o ba r', 
'fo o b ar', 
'fo o b a r', 
'f oobar', 
'f ooba r', 
'f oob ar', 
'f oob a r', 
'f oo bar', 
'f oo ba r', 
'f oo b ar', 
'f oo b a r', 
'f o obar', 
'f o oba r', 
'f o ob ar', 
'f o ob a r', 
'f o o bar', 
'f o o ba r', 
'f o o b ar', 
'f o o b a r'] 
+0

điều này tạo ra kết quả sai – jamylak

+0

@jamylak - không có nó không. – root

+0

bạn có 32 kết hợp trái ngược với OP của 64. Ngoài ra combo của bạn là ngược. Một cái gì đó như 'cho x trong sản phẩm (('', ''), lặp lại = len (văn bản)):' 'L.append (''. Join (chain.from_iterable (izip (văn bản, đảo ngược (x)))) .rstrip()) 'nên sửa chữa nó – jamylak

1

Đây có lẽ không phải là cách hiệu quả nhất, nhưng tôi sẽ tạo hai danh sách. Một có một chữ cái là mỗi phần tử, và cái còn lại có mỗi chữ cái theo sau là một dấu cách. Một khoảng cách có thể được tạo ra bằng cách chọn giữa hai danh sách cho mỗi chữ cái (có thể được mô hình hóa dưới dạng số nhị phân, trong đó 0 = không có dấu cách và 1 = dấu cách)

def spacify(word): 
    no_space = list(word[:-1]) 
    spaced = [lt + ' ' for lt in no_space] 
    for i in range(2 ** (len(word) - 1)): 
     spaced_word = "" 
     for j in range(len(word) - 1): 
      if i % 2 == 0: 
       spaced_word += no_space[j] 
      else: 
       spaced_word += spaced[j] 
      i = i // 2 # Or use bit shifting to be fancy 
    print spaced_word + word[-1] 
+0

Không phải là giải pháp chung. Không hiệu quả. –

+0

thực sự, bạn chỉ cần lên tới 2 ** 4 (16 kết hợp), bởi vì bạn phải bỏ đi chữ cái đầu tiên và cuối cùng của từ đó. – lucasg

+1

Giải pháp không hoàn toàn chính xác, bởi vì không có không gian sau chữ cái cuối cùng. Điều này cũng làm giảm số lượng khả năng. Đang sửa ngay bây giờ. – Titandrake

1
from itertools import combinations 

def gen_spaces(data): 
    return_value = [] 
    size = len(data)-1 
    for num_spaces in range(size): 
     for comb in combinations(range(size), num_spaces+1): 
      data_as_list = list(data) 
      for i in comb: 
       data_as_list[i] +=' ' 
      return_value.append(''.join(data_as_list)) 
    return return_value 

from pprint import pprint 

pprint(gen_spaces("foobar")) 

Output:

['f oobar', 
'fo obar', 
'foo bar', 
'foob ar', 
'fooba r', 
'f o obar', 
'f oo bar', 
'f oob ar', 
'f ooba r', 
'fo o bar', 
'fo ob ar', 
'fo oba r', 
'foo b ar', 
'foo ba r', 
'foob a r', 
'f o o bar', 
'f o ob ar', 
'f o oba r', 
'f oo b ar', 
'f oo ba r', 
'f oob a r', 
'fo o b ar', 
'fo o ba r', 
'fo ob a r', 
'foo b a r', 
'f o o b ar', 
'f o o ba r', 
'f o ob a r', 
'f oo b a r', 
'fo o b a r', 
'f o o b a r'] 

cập nhật:

bạn nói bạn cần "tất cả po kết hợp ssible của chuỗi có khoảng trắng giữa các ký tự ", nhưng đồng thời ví dụ bạn đã cung cấp trong [Out] không phản ánh điều đó (tức là bạn có "f o o bar" hai lần, "f ooba r" là mất tích, vv)

Trong câu trả lời này tôi giả sử bạn thực sự muốn "tất cả các kết hợp có thể của một chuỗi với khoảng trống giữa các ký tự"

0

Sử dụng thư viện itertools (nhưng nó là khá nhiều giống như Titandrake):

import itertools 

foobar = "foobar" 
foobar_r = range(len(foobar)) 


for integer in range(2**5): 
    binary_mask = [ bit for bit in itertools.ifilter(lambda x: (integer >>x)&0x01, foobar_r) ] 
    spaces_mask = [ " " if i in binary_mask else "" for i in foobar_r ] 

    # Zip-it Crash-it Melt-it Upgrade-it 
    print integer, "".join([ "".join([str(char) for char in zip_char ]) for zip_char in itertools.izip(foobar,spaces_mask)]) 
1

Dưới đây là một ý tưởng thực hiện đệ quy của tôi trên:

def string_spaces(s): 
    ret = set([s]) # use a set rather than a list to prevent duplicates 
    for i in range(1, len(s)): 
     for fst in string_spaces(s[:i]): 
      for snd in string_spaces(s[i:]): 
       ret.add(fst + ' ' + snd) 
    return ret 

Ví dụ:

In [11]: string_spaces('foo') 
Out[11]: set(['foo', 'f o o', 'f oo', 'fo o']) 

NB: Python có một giới hạn đệ quy 1000 khung stack, vì vậy đây sẽ sụp đổ cho chuỗi rất dài (dài hơn 1.000 ký tự).

2
from itertools import product 

text = "foobar" 
L = [''.join(reversed(x)).rstrip() 
    for x in product(*[(c, c+' ') for c in reversed(text)])] 
print L 

['foobar', 'f oobar', 'fo obar', 'f o obar', 'foo bar', 'f oo bar', 'fo o bar', 'f o o bar', 'foob ar', 'f oob ar', 'fo ob ar', 'f o ob ar', 'foo b ar', 'f oo b ar', 'fo o b ar', 'f o o b ar', 'fooba r', 'f ooba r', 'fo oba r', 'f o oba r', 'foo ba r', 'f oo ba r', 'fo o ba r', 'f o o ba r', 'foob a r', 'f oob a r', 'fo ob a r', 'f o ob a r', 'foo b a r', 'f oo b a r', 'fo o b a r', 'f o o b a r', 'foobar', 'f oobar', 'fo obar', 'f o obar', 'foo bar', 'f oo bar', 'fo o bar', 'f o o bar', 'foob ar', 'f oob ar', 'fo ob ar', 'f o ob ar', 'foo b ar', 'f oo b ar', 'fo o b ar', 'f o o b ar', 'fooba r', 'f ooba r', 'fo oba r', 'f o oba r', 'foo ba r', 'f oo ba r', 'fo o ba r', 'f o o ba r', 'foob a r', 'f oob a r', 'fo ob a r', 'f o ob a r', 'foo b a r', 'f oo b a r', 'fo o b a r', 'f o o b a r'] 
+0

rất thanh lịch. tôi chưa bao giờ nghĩ đến việc sử dụng 'sản phẩm' với' đảo ngược' theo cách này =) – alvas

1

giải pháp đệ quy. (Có thể cần phải sử dụng các sys.setrecursionlimit() cho chuỗi dài hơn):

def gen_perm(my_str): 
    if len(my_str) <= 1 : 
     return [my_str] 
    rest_perms = gen_perm(my_str[1:]) 
    all_perms = [my_str[0] + perm for perm in rest_perms ] + [my_str[0] + ' ' + perm for perm in rest_perms] 
    return all_perms 

print(gen_perm("foobar"))