Toán học 337 418 372
Sau khi thử không thành công để thực hiện bằng Mathicala LongestCommonSubsequencePositions
, tôi chuyển sang khớp mẫu.
v=Length;
p[t_]:=Subsets[t,{2}];
f[w_]:=Module[{c,x,s=Flatten,r={{a___,Longest[y__]},{y__,b___}}:>{{a,y},{y,b},{y},{a,y,b}}},
c=p@w;
x=SortBy[Cases[s[{#/.r,(Reverse@#)/.r}&/@c,1],{_,_,_,_}],v[#[[3]]]&][[-1]];
Append[Complement[w,{x[[1]],x[[2]]}],x[[4]]]]
g[r_]:=With[{h=Complement[r,Cases[Join[p@r,p@Reverse@r],y_/;!StringFreeQ@@y:>y[[2]]]]},
FixedPoint[f,Characters/@h,v@h-1]<>""]
Quy tắc khớp mẫu,
r={{a___,Longest[y__]},{y__,b___}}:> {{a,y},{y,b},{y},{a,y,b}}},
lấy một cặp từ được sắp xếp (được biểu thị dưới dạng danh sách các ký tự) và trả về: (1) các từ {a,y}
và {y,b}
theo sau là (2) chuỗi con chung y
, liên kết phần cuối của một từ với đầu của từ khác, và, cuối cùng, từ kết hợp {a,y,b}
sẽ thay thế các từ đầu vào. Xem Belisarius để biết ví dụ liên quan: https://mathIALa.stackexchange.com/questions/6144/looking-for-longest-common-subopes-solution
Ba ký tự gạch dưới liên tiếp biểu thị rằng phần tử là một chuỗi gồm 0 hoặc nhiều ký tự.
Reverse
được sử dụng sau này để đảm bảo rằng cả hai đơn hàng đều được kiểm tra. Những cặp chia sẻ chữ cái liên kết được trả lại không thay đổi và bỏ qua.
Chỉnh sửa :
Các từ sau sẽ xóa khỏi danh sách các từ "bị chôn vùi" (nghĩa là chứa đầy đủ) trong một từ khác, (để đáp lại nhận xét của @ flornquake).
h=Complement[r,Cases[Join[p@r,p@Reverse@r],x_/;!StringFreeQ@@x:> x[[2]]]]
Ví dụ :
{{"D", "O", "L", "O", "R", "E"}, {"L", "O", "R", "E", "M"}} /. r
trả lại
{{"D", "O", "L", "O", "R", "E"}, {"L", "O", "R", "E", "M"}, { "L", "O", "R", "E"}, {"D", "O", "L", "O", "R", "E", "M"}}
Sử dụng
g[{"LOREM", "ORE", "R"}]
AbsoluteTiming[g[{"AD", "DO", "DOLOR", "DOLORE", "LOREM", "MAGNA", "SED", "ORE", "R"}]]
"LOREM"
{0,006256, "SEDOLOREMAGNAD"}