最长公共子序列(LCS)
长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。
分析
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
String s1 = cin.next().trim();
String s2 = cin.next().trim();
int len1 = s1.length();
int len2 = s2.length();
int[][] lcs = new int[len1+5][len2+5];
int[][] dir = new int[len1+5][len2+5];
for(int i=1; i<=len1; i++){
for(int j=1; j<=len2; j++){
if(s1.charAt(i-1) == s2.charAt(j-1)){
lcs[i][j] = lcs[i-1][j-1] + 1;
dir[i][j] = 1;
}else{
if(lcs[i-1][j] > lcs[i][j-1]){
lcs[i][j] = lcs[i-1][j];
dir[i][j] = 2;
}else{
lcs[i][j] = lcs[i][j-1];
dir[i][j] = 3;
}
}
}
}
System.out.println("最长公共子序列长度:"+lcs[len1][len2]);
String tra = getTrajectory(dir, len1, len2, s1);
System.out.println(tra);
cin.close();
}
//最优解(不唯一)
private static String getTrajectory(int[][] dir, int i, int j, String s) {
if(i == 0 || j == 0) return "";
if(dir[i][j] == 1){
return getTrajectory(dir, i-1, j-1, s) + String.valueOf(s.charAt(i-1));
}
if(dir[i][j] == 2) {
return getTrajectory(dir, i-1, j, s);
}
if(dir[i][j] == 3){
return getTrajectory(dir, i, j-1, s);
}
return "";
}
}
/*
样例:
13456778
357486782
最长公共子序列长度:5
35778
abcbdb
acbbabdbb
最长公共子序列长度:5
acbdb
*/
如有错误或不合理的地方,敬请指正~
加油!!