问题
给定两个序列X、Y,找出X和Y的最长公共子序列。
子序列:在某个序列中删去若干元素后得到的序列。
import java.util.Scanner;
/**
* 最长公共子序列
* @author noTalent
* 2018/3/6
*/
public class LCS {
/**
* 主方法
* @param args
*/
public static void main(String[] args) {
/* 获取输入 */
String strf, strs;
Scanner cin = new Scanner(System.in);
strf = cin.nextLine();
strs = cin.nextLine();
cin.close();
/* 动态规划求解 */
int [][]c = new int[strf.length() + 1][strs.length() + 1];
int [][]b = new int[strf.length() + 1][strs.length() + 1];
System.out.println(lcsLength(strf, strs, c, b));
lcs(strf.length(), strs.length(), strf, b);
}
/**
* 动态规划获取最长公共子序列长度
* @param strf
* @param strs
* @param c
* @param b
* @return
*/
public static int lcsLength(String strf, String strs, int [][]c, int[][]b) {
int i, j;
/* 空序列:边缘置0 */
for (i = 1; i <= strf.length(); i++) c[i][0] = 0;
for (i = 1; i <= strs.length(); i++) c[0][i] = 0;
/* 动态规划 */
for (i = 1; i <= strf.length(); i++) {
for (j = 1; j <= strs.length(); j++) {
if (strf.charAt(i - 1) == strs.charAt(j - 1)) {
c[i][j] = c[i - 1][j - 1] + 1;
b[i][j] = 1;
}
else if (c[i - 1][j] >= c[i][j - 1]) {
c[i][j] = c[i - 1][j];
b[i][j] = 2;
}
else {
c[i][j] = c[i][j - 1];
b[i][j] = 3;
}
}
}
/* 返回最长公共子序列长度 */
return c[strf.length()][strs.length()];
}
/**
* 递归获取最长公共子序列
* @param i
* @param j
* @param strf
* @param b
*/
public static void lcs(int i, int j, String strf, int [][]b) {
if (i == 0 || j == 0) return;
if (b[i][j] == 1) {
lcs(i - 1, j - 1, strf, b);
System.out.print(strf.charAt(i - 1));
}
else if (b[i][j] == 2) {
lcs(i - 1, j, strf, b);
}
else {
lcs(i, j - 1, strf, b);
}
}
}