对于两个字符串,求取最长公共子序列
package practice2;
import java.util.*;
/*
* 最长公共子序列
*/
public class LargestSubSequence {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
largestSubSequence(input.next(),input.next());
}
public static void largestSubSequence(String s1,String s2) {
int L1 = s1.length();
int L2 = s2.length();
/*
dp[i][j] 串A的第i个字符与串B的第j个字符的最长公共子序列
ch[i][j] 记录路径
dp[i][j] = dp[i-1][j-1] + 1 A[i] = B[i];
Max(dp[i][j-1],dp[i-1][j])
*/
int[][] dp = new int[L1+1][L2+2];
char[][] ch = new char[L1+1][L2+1];
for(int i = 0;i < L1+1;i++) {
for(int j = 0;j < L2+1;j++) {
if(i == 0 || j == 0) {
dp[i][j] = 0;
} else {
if(s1.charAt(i-1) == s2.charAt(j-1)) {
/*
* 如果值相等,就说明现在的值来自于左上角,此时序列长度加一
* 由 \ 记录下路径
*/
dp[i][j] = dp[i-1][j-1] + 1;
ch[i][j] = '\\' ;
} else {
/*
* | 代表值来自于dp[i-1][j]值更大
* —— 说明值来自于dp[i][j-1]值更大
*/
if(dp[i-1][j] > dp[i][j-1]) {
dp[i][j] = dp[i-1][j];
ch[i][j] = '|' ;
} else {
dp[i][j] = dp[i][j-1];
ch[i][j] = '—' ;
}
}
}
}
}
/*
* 打印值
*/
for(int i = 0;i < L1+1;i++) {
for(int j = 0;j < L2+1;j++) {
if(j == L2) {
System.out.println(dp[i][j]);
} else {
System.out.print(dp[i][j]+" ");
}
}
}
System.out.println();
/*
* 打印路径
*/
for(int i = 0;i < L1+1;i++) {
for(int j = 0;j < L2+1;j++) {
if(j == L2) {
System.out.println(ch[i][j]);
} else {
System.out.print(ch[i][j]+" ");
}
}
}
/*
* 打印子序列
*/
StringBuffer str = new StringBuffer("");
int i = L1;
int j = L2;
boolean f = true;
while(i > 0) {
while(j > 0) {
if(ch[i][j] == '\\') {
str.append(s1.charAt(i-1));
i--;
j--;
} else if(ch[i][j] == '|'){
i--;
} else {
j--;
}
if(dp[i][j] == 0) {
f =false;
break;
}
}
if(!f) {
break;
}
}
System.out.println(str.reverse());
}
}