Подстроки строки с использованием Python
Сколько подстрок вы можете сделать из строки, как abcd
?
Как я могу получить все его подстроки:
['a', 'b', 'c', 'd', 'ab', 'bc', 'cd', 'abc', 'bcd', 'abcd']
5 ответов
Попробуй это:
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
Этот код является немного более громоздким и, вероятно, может быть оптимизирован для отступов, но он подойдет для доказательства концепции.
Будет ли это делать?
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']
Чтобы упорядочить по длине, используйте сортировку key=len
,
Я думаю, что это тоже работает, и хотя оно не самое эффективное, оно имеет привлекательный характер использования менее сложных функций.
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
а также ab
появится дважды.
Там есть два вопроса.
Первый, 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']
Второй вопрос - как повторить ваш пример (который не является "комбинацией"). Вы можете сделать это с помощью этого кода:
>>> [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']
Это то, что вы хотите:
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']