数学337 418 372
在尝试使用Mathematica的实现失败后LongestCommonSubsequencePositions
,我转向了模式匹配。
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]<>""]
模式匹配规则
r={{a___,Longest[y__]},{y__,b___}}:> {{a,y},{y,b},{y},{a,y,b}}},
需要的有序对的话(表示为字符的列表),并返回:(1)的话,{a,y}
和{y,b}
随后(2)的共同子串,y
即通一个单词的末尾与其他单词的开始,和,最后,{a,y,b}
将替换输入单词的组合单词。参见贝利萨留斯的相关示例:https : //mathematica.stackexchange.com/questions/6144/looking-for-longest-common-substring-solution
三个连续的下划线字符表示该元素是一个零个或多个字符的序列。
Reverse
稍后使用以确保两个订单都经过测试。那些共享可链接字母的对将保持不变并被忽略。
编辑:
以下内容从列表中删除了另一个单词中“埋藏”(即完全包含)的单词(以响应@flornquake的评论)。
h=Complement[r,Cases[Join[p@r,p@Reverse@r],x_/;!StringFreeQ@@x:> x[[2]]]]
范例:
{{"D", "O", "L", "O", "R", "E"}, {"L", "O", "R", "E", "M"}} /. r
退货
{{“ D”,“ O”,“ L”,“ O”,“ R”,“ E”},{“ L”,“ O”,“ R”,“ E”,“ M”},{ “ L”,“ O”,“ R”,“ E”}},{“ D”,“ O”,“ L”,“ O”,“ R”,“ E”,“ M”}}
用法
g[{"LOREM", "ORE", "R"}]
AbsoluteTiming[g[{"AD", "DO", "DOLOR", "DOLORE", "LOREM", "MAGNA", "SED", "ORE", "R"}]]
“ LOREM”
{0.006256,“ SEDOLOREMAGNAD”}