最长公共子序列

来源:互联网 发布:知乎个性域名修改 编辑:程序博客网 时间:2024/05/16 09:46

问题描述

最长公共子序列(LCS)问题:给定两个序列 X=<x₁,x₂,x₃...xm>和Y=<y₁,y₂,y₃...yn>,要找出X和Y的一个最长的公共子序列,事实上,最长的公共子序列问题也有最优子序列结构性质,有如下定理:

定理:LCS的最优子结构性质:
设序列

X=<x₁,x₂,x₃...xm>和

Y=<y₁,y₂,y₃...yn>的最长的一个公共子序列为Z

=<z₁,z₂,z₃...zk>,则:

①若xm = yn,则 zk=xm=yn 且Z(k-1)是X(x-1)和Y(y-1)的最长的公共子序列;

②若xm≠yn 且 zk≠xm ,则Z是X(m-1)和Y的最长的子序列;

③若xm≠yn 且 zk≠yn ,则Z是Y(n-1)和X的最长的子序列;

这个定理告诉我们:两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,因此,最长公共子序列问题具有最优子结构性质。


这里我们采用子问题的递归结构:

利用刚刚的最优子结构性质可知:要找出

X=<x₁,x₂,x₃...xm>和

Y=<y₁,y₂,y₃...yn>的最长公共子序列,可以按以下的递归方式进行:c[i][j]用来记录序列Xi 和Yi的最长公共子序列长度:

① i=0或者j=0  c[i][j]=0;

②i,j>0,且xi=yj,  c[i-1][j-1]+1  ;这里的1指的是xm(=yn);

③i,j>0,且xi≠yj ,  max(c[i-1][j],c[i][j-1]);

这里我们定义一个数组b[i][j]用来记录c[i][j] 处于哪一种子问题中,在打印LCS时,通过分析b[i][j]的取值情况就可以知道c[i][j]是上述三种子问题的哪一种,然后就可以调用方法俩打印出序列。

代码如下:
计算子问题最优值;


构造 最长子序列:

并打印序列x和y的最长公共子序列;


0 0