最长公共子序列问题:
伪代码:
- Procedure LCS_LENGTH(X,Y);LCS_LENGTH(X,Y);
- begin
- m:=length[X];
- n:=length[Y];
- for i:=1 to m do c[i,0]:=0;
- for j:=1 to n do c[0,j]:=0;
- for i:=1 to m do
- for j:=1 to n do
- if x[i]=y[j] then
- begin
- c[i,j]:= c[i-1,j -1]+ 1;
- b[i,j]:="↖";
- end
- else if c[i -1,j]≥ c[i,j -1] then
- begin
- c[i,j]:= c[i-1,j];
- b[i,j]:= "↑" ;
- end
- else
- begin
- c[i,j]:= c[j-1];
- b[i,j]:="←"
- end;
- return(c,b);
- end
在这个问题中图示:
在LCS算法中,每一次递归调用使i或j减1,因此算法的时间复杂度为O(m+n)。
例如,设所给的两个序列为X=<A,B,C,B,D,A,B>和Y=<B,D,C,A,B,A>。由算法LCS_LENGTH和LCS计算出的结果如下图所示:
我来说明下此图(参考算法导论)。在序列X={A,B,C,B,D,A,B}和 Y={B,D,C,A,B,A}上,由LCS_LENGTH计算出的表c和b。第i行和第j列中的方块包含了c[i,j]的值以及指向b[i,j]的箭头。在c[7,6]的项4,表的右下角为X和Y的一个LCS<B,C,B,A>的长度。对于i,j>0,项c[i,j]仅依赖于是否有xi=yi,及项c[i-1,j]和c[i,j-1]的值,这几个项都在c[i,j]之前计算。为了重构一个LCS的元素,从右下角开始跟踪b[i,j]的箭头即可,这条路径标示为阴影,这条路径上的每一个“↖”对应于一个使xi=yi为一个LCS的成员的项(高亮标示)。
所以根据上述图所示的结果,程序将最终输出:“B C B A”。