Посмотрите на алгоритм Word break, это его вариант с существенной разницей в том, что слова не поступают из предопределенного словаря, но вместо этого в конечном наборе должно быть фиксированное число из них.
Основная идея состоит в том, чтобы выполнить итерацию с вашего ввода с начала, отрезать его и обработать правую часть рекурсивно.
Считая функцию с прототипом
def rec(input, n):
это псевдо-код:
if n == 1:
final_set.append([input[i:]])
else:
for i in range (0, len(input) - n + 1):
for rec_set in rec(input[i:], n - 1):
final_set.append(merge(input[:i], rec_set))
Используя ваш пример, мы имеем:
rec('foobar', 3)
= {['f', rec('oobar', 2)], ['fo', rec('obar', 2)], ['foo', rec('bar', 2)], ['foob', rec('ar', 2)]}
= {['f','o', rec('obar', 1)], ['f','oo', rec('bar', 1)], ['f','oob', rec('ar', 1)], ['f','ooba', rec('r', 1)], ['fo', 'o', rec('bar', 1)], ['fo', 'ob', rec('ar', 1)], ['fo', 'oba', rec('r', 1)], ['foo', 'b', rec('ar', 1)], ['foo', 'ba', rec('r', 1)], ['foob', 'a', rec('r', 1)]}
= {['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']}
Важно помнить, до кэш частичные результаты во избежание r epeat делает ту же работу снова и снова. Например, если вы уже рассчитали rec('oobar', 2)
, сохраните результат в некотором кеше (например, словарь подходит для этого) и проверьте в начале функции, были ли вы уже рассчитаны все возможные комбинации для указанной входной строки и n
. Это уменьшает временную сложность от экспоненциального до полиномиального.
Подсказка: подумайте о разделителях между группами. Отрицательное пространство. –