11

次のような文字列からいくつの部分文字列を作成できますabcdか?

すべての部分文字列を取得するにはどうすればよいですか。

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

5 に答える 5

12

これを試して:

def consecutive_groups(iterable):
    s = tuple(iterable)
    for size in range(1, len(s)+1):
        for index in range(len(s)+1-size):
            yield iterable[index:index+size]

>>> print list(consecutive_groups('abcd'))
['a', 'b', 'c', 'd', 'ab', 'bc', 'cd', 'abc', 'bcd', 'abcd']

また、組み合わせの数は、1 から文字列の長さまでの合計に単純に等しくなり、これは に相当しn * (n + 1) / 2ます。

ちなみに、重複を避けたい場合は、次のように、ジェネレーター関数でローカルに定義されたセットを使用できます。

def consecutive_groups(iterable):
    s = tuple(iterable)
    seen = set()
    for size in range(1, len(s)+1):
        for index in range(len(s)+1-size):
            slc = iterable[index:index+size]
            if slc not in seen:
                seen.add(slc)
                yield slc

そのコードはもう少し扱いに​​くく、おそらくインデント用に最適化できますが、概念実証には十分です。

于 2012-10-17T23:39:28.177 に答える
11

これでいいですか?

import itertools
def substrings(x):
    for i, j in itertools.combinations(xrange(len(x)+1), 2):
        yield x[i:j]

またはジェネレータ式として:

(x[i:j] for i, j in itertools.combinations(xrange(len(x)+1), 2))

例の展開された結果は次のようになります。

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

長さで並べ替えるには、sortを使用しますkey=len

于 2012-10-18T00:58:54.283 に答える
2

これはあなたが望むものです:

In [260]: S = 'abcd'

In [261]: list(itertools.chain.from_iterable([list(itertools.combinations(S,i)) for i in range(1,len(S))]))
Out[261]: 
[('a',),
 ('b',),
 ('c',),
 ('d',),
 ('a', 'b'),
 ('a', 'c'),
 ('a', 'd'),
 ('b', 'c'),
 ('b', 'd'),
 ('c', 'd'),
 ('a', 'b', 'c'),
 ('a', 'b', 'd'),
 ('a', 'c', 'd'),
 ('b', 'c', 'd')]

または、それらすべてを文字列として本当に必要な場合は、次のようにすることができます。

In [262]: combos  = list(itertools.chain.from_iterable([list(itertools.combinations(S,i)) for i in range(1,len(S))]))

In [263]: [''.join(c) for c in combos]
Out[263]: 
['a',
 'b',
 'c',
 'd',
 'ab',
 'ac',
 'ad',
 'bc',
 'bd',
 'cd',
 'abc',
 'abd',
 'acd',
 'bcd']

編集 の部分文字列のみを取得するにはS:

In [270]: list(itertools.chain.from_iterable([[S[i:i+k] for i in range(len(S)-k)] for k in range(1,len(S)+1)])) + [S]
Out[270]: ['a', 'b', 'c', 'ab', 'bc', 'abc', 'abcd']
于 2012-10-18T00:03:11.407 に答える
2

これも機能すると思います。最も効率的ではありませんが、複雑でない機能を使用できるという魅力があります。

S = "abcd"
substrings = [S[i:j] for i in range(len(S)) for j in range(i+1,len(S)+1)]
substrings.sort(key=len)

ただし、このアプローチでは、表示される可能性のある同一の部分文字列は削除されないことに注意してください。たとえば、元の部分文字列が"abcdab", a,bの場合、 ab2 回表示されます。

于 2012-10-18T00:35:09.540 に答える
1

そこで2つの質問があります。

1つ目How many substrings can you make out of a string like “abcd”?は、次のような組み合わせです。

import itertools
s='abcd'
com=[list(itertools.combinations(s,x)) for x in range(1,len(s)+1)]

print [''.join(e) for e in sum(com,[])]

プリント:

['a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'bc', 'bd', 'cd', 'abc', 'abd', 'acd', 'bcd', 'abcd']

2 番目の質問は、例を複製する方法です (これは「組み合わせ」ではありません)。次のコードでそれを行うことができます。

>>> [s[i:i+j] for j in range(1,len(s)+1) for i in range(len(s)-j+1)]
['a', 'b', 'c', 'd', 'ab', 'bc', 'cd', 'abc', 'bcd', 'abcd']
于 2012-10-18T00:06:47.497 に答える