Чтобы получить вывод, показанный в вашем вопросе, хотя и не в том же порядке, я бы так и сделал.
Я буду использовать Mathematica код, но концепции универсальны.
string = "Mary had a little lamb";
set = StringSplit[string]
n = Length@set
{"Mary", "had", "a", "little", "lamb"}
5
Так что вам понадобится функция, которая разбивает предложение на слова (StringSplit).
Тогда вам понадобится функция для генерации целочисленных разбиений и функция перестановки, которая знает о дублированных элементах. Алгоритмы для обоих можно найти здесь, на StackOverflow.
IntegerPartitions[n]
{{5}, {4, 1}, {3, 2}, {3, 1, 1}, {2, 2, 1}, {2, 1, 1, 1}, {1, 1, 1, 1, 1}}
Как только мы переставим каждый раздел («для каждого» - /@
), мы получим все способы линейно разделить набор из пяти частей:
parts = Join @@ Permutations /@ IntegerPartitions[n]
{{5}, {4, 1}, {1, 4}, {3, 2}, {2, 3}, {3, 1, 1}, {1, 3, 1},
{1, 1, 3}, {2, 2, 1}, {2, 1, 2}, {1, 2, 2}, {2, 1, 1, 1}, {1, 2, 1, 1},
{1, 1, 2, 1}, {1, 1, 1, 2}, {1, 1, 1, 1, 1}}
Наконец, нам нужна функция для разбиения набора в соответствии с последовательностями длин. Я называю мой динамический раздел:
dynamicPartition[set, #] & /@ parts // Column
{{Mary,had,a,little,lamb}}
{{Mary,had,a,little},{lamb}}
{{Mary},{had,a,little,lamb}}
{{Mary,had,a},{little,lamb}}
{{Mary,had},{a,little,lamb}}
{{Mary,had,a},{little},{lamb}}
{{Mary},{had,a,little},{lamb}}
{{Mary},{had},{a,little,lamb}}
{{Mary,had},{a,little},{lamb}}
{{Mary,had},{a},{little,lamb}}
{{Mary},{had,a},{little,lamb}}
{{Mary,had},{a},{little},{lamb}}
{{Mary},{had,a},{little},{lamb}}
{{Mary},{had},{a,little},{lamb}}
{{Mary},{had},{a},{little,lamb}}
{{Mary},{had},{a},{little},{lamb}}