Последовательные подмножества списка - PullRequest
11 голосов
/ 14 января 2012

С учетом списка скажем

{"a", "b", "c", "d"}

Есть ли более простой способ создать список последовательных подмножеств, как этот (порядок результата не важен)

{
 {"a"},
 {"a b"},
 {"a b c"},
 {"a b c d"},
 {"b"},
 {"b c"},
 {"b c d"},
 {"c"},
 {"c d"},
 {"d"}
}

Ответы [ 7 ]

19 голосов
/ 14 января 2012

Я думаю, что мне нравится это больше всего:

set = {"a", "b", "c", "d"};

ReplaceList[set, {___, x__, ___} :> {x}]

С присоединением строки:

ReplaceList[set, {___, x__, ___} :> "" <> Riffle[{x}, " "]]

В том же духе, специфично для строк:

StringCases["abcd", __, Overlaps -> All]

Так как Насер говорит, что я обманываю, вот более ручной подход, который также имеет большую эффективность на больших сетах:

ClearAll[f, f2]
f[i_][x_] := NestList[i, x, Length@x - 1]
f2[set_]  := Join @@ ( f[Most] /@ f[Rest][set] )

f2[{"a", "b", "c", "d"}]
14 голосов
/ 14 января 2012
Flatten[Partition[{a, b, c, d}, #, 1] & /@ {1, 2, 3, 4}, 1]

дает

{{a}, {b}, {c}, {d}, {a, b}, {b, c}, {c, d}, {a, b, c}, {b, c , д}, {а, b, c, d}}

7 голосов
/ 14 января 2012

Как насчет этого:

origset = {"a", "b", "c", "d"};

bdidxset = Subsets[Range[4], {1, 2}]

origset[[#[[1]] ;; #[[-1]]]] & /@ bdidxset

, что дает

{{"a"}, {"b"}, {"c"}, {"d"}, {"a", "b"}, {"a", "b", "c"}, {"a", "b", 
  "c", "d"}, {"b", "c"}, {"b", "c", "d"}, {"c", "d"}}
5 голосов
/ 14 января 2012

Мне больше нравится метод TomD, но вот что мне пришло в голову, без обработки строк:

set = {"a", "b", "c", "d"};

n = Length@set;

Join @@ Table[set~Take~{s, f}, {s, n}, {f, s, n}] // Column

Mathematica graphics

1 голос
/ 14 января 2012

в одну сторону:

makeList[lst_] := Map[ Union[lst[[1 ;; #]]] &, Range@Length[lst]]
r = Map[makeList[lst[[# ;; -1]]] &, Range@Length[lst]];
Flatten[r, 1]

дает

{{"a"}, 
 {"a", "b"}, 
 {"a", "b", "c"}, 
 {"a", "b", "c", "d"}, 
 {"b"},
 {"b", "c"},
 {"b", "c", "d"},
 {"c"}, 
 {"c", "d"}, 
 {"d"}}
1 голос
/ 14 января 2012

Вот одно из возможных решений

a={"a","b","c","d"};
StringJoin@Riffle[#, " "] & /@ 
  DeleteDuplicates[
   LongestCommonSubsequence[a, #] & /@ 
    DeleteCases[Subsets@a, {}]] // Column

Результат

a
b
c
d
a b
b c
c d
a b c
b c d
a b c d
1 голос
/ 14 января 2012

Вы можете сделать это так:

a = {"a", "b", "c", "d"};
b = List[StringJoin[Riffle[#, " "]]] & /@
  Flatten[Table[c = Drop[a, n];
    Table[Take[c, i], {i, Length[c]}],
    {n, 0, Length[a]}], 1]

вывод будет выглядеть так:

{{"a"}, {"a b"}, {"a b c"}, {"a b c d"}, {"b"}, {"b c"}, {"b c d"}, {"c"}, {"c d"}, {"d"}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...