2012-01-14 40 views
11

Cho một danh sách nóiSubsets tuần tự của một danh sách

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

Có cách nào dễ dàng hơn để tạo ra danh sách các tập con tuần tự như thế này (theo thứ tự kết quả là không quan trọng)

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

Trả lời

19

Tôi nghĩ tôi thích điều này tốt nhất của tất cả:

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

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

Với chuỗi tham gia:

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

Trong một tĩnh mạch tương tự, cụ thể cho chuỗi:

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

Kể từ khi Nasser nói rằng tôi đang lừa dối, đây là một phương pháp thủ công hơn mà còn có hiệu quả cao hơn trên bộ lớn:

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

f2[{"a", "b", "c", "d"}] 
+0

+1, đó không phải là công bằng của ông Wizard, bạn đang cho phép Mathematica làm tất cả các công việc khó khăn bằng cách sử dụng phương pháp này. Bạn phải làm điều gì đó! – Nasser

+0

Đây là phép thuật, không phải lập trình! – acl

+3

Điều này thật tuyệt! và tôi nghĩ nó phù hợp với quan điểm cốt lõi của Mathematica hơn là gian lận :) – Silvia

1

Bạn có thể làm điều đó như thế này:

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] 

đầu ra sẽ trông như thế này:

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

Dưới đây là một giải pháp có thể

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

quả

a 
b 
c 
d 
a b 
b c 
c d 
a b c 
b c d 
a b c d 
7

Làm thế nào về điều này:

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

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

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

mang đến cho

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

một cách:

makeList[lst_] := Map[ Union[lst[[1 ;; #]]] &, [email protected][lst]] 
r = Map[makeList[lst[[# ;; -1]]] &, [email protected][lst]]; 
Flatten[r, 1] 

cho

{{"a"}, 
{"a", "b"}, 
{"a", "b", "c"}, 
{"a", "b", "c", "d"}, 
{"b"}, 
{"b", "c"}, 
{"b", "c", "d"}, 
{"c"}, 
{"c", "d"}, 
{"d"}} 
14
Flatten[Partition[{a, b, c, d}, #, 1] & /@ {1, 2, 3, 4}, 1] 

cho

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

+0

+1 , Phức tạp hơn anh Wizard, nhưng vẫn tốt. – rcollyer

5

Tôi thích phương pháp TomD của tốt hơn, nhưng đây là những gì đến tâm trí của tôi, xử lý chuỗi sans:

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

n = [email protected]; 

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

Mathematica graphics

+1

Tại sao hai câu trả lời? – abcd

+1

@yoda Đại diện nhiều hơn, tất nhiên là –

+3

@yoda Tôi nghĩ câu trả lời có tính cách hoàn toàn khác.Tôi thấy một vấn đề với câu trả lời omnibus: nó không rõ ràng * mà mọi người đang bỏ phiếu cho mục đích bỏ phiếu, và cử tri có thể cảm thấy họ phải bỏ phiếu cho các phương pháp họ không thích (hoặc thất bại hoàn toàn) nếu họ muốn bỏ phiếu cho một người họ làm. Trái ngược với khẳng định của Peter, tôi không phải là người chơi game. –

Các vấn đề liên quan