用动态规划算法实现最长公共子序列问题的算法
public class longestCommonSubsequence {
//构造追踪数组rec,记录子问题来源
private static String[][] rec;
public static void main(String[] args){
char[] X = {'A', 'B', 'C', 'B', 'D', 'A', 'B'};
char[] Y = {'B', 'D', 'C', 'A', 'B', 'A'};
int n = X.length;
int m = Y.length;
//为追踪数组定义大小
rec = new String[n+1][m+1];
int maxLength = longestCommonSubsequence(X, Y, n, m);
System.out.println("最长子数组长度:\n"+maxLength+"\n最长子数组为:");
printLCS(X, n, m);
}
private static int longestCommonSubsequence(char[] X, char[] Y, int n, int m){
//创建一个新的二维数组
int[][] C = new int[n+1][m+1];
//进行初始化
for (int i=0; i<=n; i++){
C[i][0] = 0;
}
for(int j=0; j<=m; j++){
C[0][j] = 0;
}
//算法核心
//动态规划
//依次计算子问题
for(int i=1; i<=n; i++){
//末尾不相等
for (int j=1; j<=m; j++){
if(X[i-1] == Y[j-1]){
//记录长度和决策
C[i][j] = C[i-1][j-1]+1;
rec[i][j] = "LU";
}
//末尾不相等
else if (C[i-1][j]>=C[i][j-1]){
C[i][j] = C[i-1][j];
rec[i][j] = "U";
}else{
C[i][j] = C[i][j-1];
rec[i][j] = "L";
}
}
}
return C[n][m];
}
//倒序追踪
private static void printLCS(char[] X, int i, int j){
//序列长度为0,递归终止
if(i==0 || j==0){
return ;
}
//末尾相等
if(rec[i][j].equals("LU")){
printLCS(X, i-1, j-1);
System.out.println(" "+ X[i-1]);
}//末尾不等
else if (rec[i][j].equals("U")){
printLCS(X, i-1, j);
}else{
printLCS(X, i, j-1);
}
}
}