您的位置:首页 > 其它

LCS最长公共子序列――动态规划

2013-10-18 09:15 387 查看
给定两个字符序列X{x1,x2,x3,...,xm}和Y{y1,y2,...,yn}
设最长公共子序列为Z{z1,z2...zk},那么,以下结论成立: C(i, j)的递推方程如下:
C(x, y) = 0 ,i=0,j=0
= C(i-1 ,j-1)+1i,j>0 , xi = yj
= max{ C(i-1 , j) , C(i , j-1)}i,j>0 , xi!= yj网上的一张图比较清晰地反映寻找过程,其实基本很多算法书都是参考这样的图~~~


public static int Length(char [] strX,char[]strY){
final int MAX = 1000;
int [][] C = new int[MAX][MAX];
int [][] B = new int[MAX][MAX];
int m = strX.length+1;
int n = strY.length+1;
for(int i = 0 ; i < m ; i++){
C[i][0] = 0;//初始化第一行
}
for(int j = 0 ; j < n ; j++){
C[0][j] = 1;//初始化第一列
}
for(int i = 1 ; i < m ; i++){
for(int j = 1 ; j < n ; j++){
//i-1是因为字符数组从第0个字符开始比较
if(strX[i-1]==strY[j-1]){
C[i][j] = C[i-1][j-1]+1;
B[i][j] = 1;//C[i][j]从C[i-1][j-1]得到
}else if(C[i-1][j] >= C[i][j-1]){
C[i][j] = C[i-1][j];
B[i][j] = 2;//从C[i-1][j]得到
}else{
C[i][j] = C[i][j-1];
B[i][j] = 3;//从C[i][j-1]得到
}
}
}
return C[m-1][n-1];
}
//在实际的算法运行中,可以将B数组删去,可以用C[i-1][j-1]保存B[i][j]的值
  public static void PrintCS(int[][]B,char []X, int i, int j){
if(i==0 || j==0) return ;
if(B[i][j] == 1){
PrintCS(B,X,i-1,j-1);
System.out.print(X[i-1]);
}else if(B[i][j] == 2){
PrintCS(B,X,i-1,j);
}else{
PrintCS(B,X,i,j-1);
}
}
PrintCS(B,strX,m-1,n-1);//注意m-1和n-1,因为m和n都等于length+1
B[i][j]=1,C[i][j]从C[i-1][j-1]得到;B[i][j]=2,从C[i-1][j]得到;B[i][j]=3,从C[i][j-1]得到

本文出自 “再累也要开心D” 博客,请务必保留此出处http://zhangzhang.blog.51cto.com/6250085/1310638
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: