-
package test; public class test3 { public static void main(String[] args) { // TODO Auto-generated method stub String []x=new String[]{"","A","C","T","C","C","T","A","G"};//比较序列X String []y=new String[]{"","C","A","T","T","C","A","G","C"};//比较序列Y int [][]b=new int [x.length][y.length];//数组b是用来存储c[i][j]是由哪个子问题的解得到的 int m,n; m=x.length-1; n=y.length-1; lcsLength(x,y,b); lcs(m,n,x,b); } public static int lcsLength(String []x,String[]y,int[][]b){ int m=x.length-1; int n=y.length-1; int [][]c=new int[m+1][n+1];//数组c存储最长公共子序列的长度 for(int i=1;i<=m;i++) c[i][0]=0; for(int i=1;i<=n;i++) c[0][i]=0; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++){ if(x[i]==y[j]){ c[i][j]=c[i-1][j-1]+1;//如果元素相等,就让最长公共子序列长度在上一个最长的长度基础上+1 b[i][j]=1;//规定为1时,表示Xi和Yj的最长公共子序列是由Xi-1和Yj-1的 //最长公共子序列加上当前元素(即指向左上角) } else if(c[i-1][j]>c[i][j-1]){ c[i][j]=c[i-1][j]; b[i][j]=2;//规定为2时,表示Xi和Yj的最长公共子序列是由Xi-1和Yj的 //最长公共子序列相同(即指向左边) } else{ c[i][j]=c[i][j-1]; b[i][j]=3;//规定为3时,表示Xi和Yj的最长公共子序列是由Xi和Y的 //最长公共子序列相同(即指向左边) } } return c[m][n]; } public static void lcs(int i,int j,String []x,int [][]b){ if(i==0||j==0) return ; if(b[i][j]==1){ lcs(i-1,j-1,x,b); System.out.print(x[i]); } else if(b[i][j]==2) lcs(i-1,j,x,b); else lcs(i,j-1,x,b); } }
如 上图(这个图是从其他地方找来的,不是我自己弄的),当b[i][j]=1时,往左上角(即最长公共子序列由左上角+1得到),其他类推
公共子序列不是集合,它与集合不同,它与原来序列的顺序有关,谁在前谁在后