最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
假设 字符串A,长度为m,c(i),表示 字符串 在第i个位置的字符(String.charAt(i))
字符串B,长度为n
则假设f(i,j)表示字符串A到第i个位置,字符 串B 到第j个位置的 最长公共字序列 的长度,则可以得到递推公式如下:
如果 A的c(i) = B的 c(j) 则 f(i,j) = f(i-1,j-1)+1
如果 A的c(i) != B的 c(j) 则 f(i,j) = max{f(i,j-1),f(i-1,j)}
则最后f(m,n) 就是最长的公共子序列
public class LCS { public static void main(String[] args) { String str1 = "123abc"; String str2 = "abc123abc"; int[][] arr = initArr(str1, str2); cal(str1, str2, arr); show(arr); showTheArr(str1, arr); } private static void cal(String str1, String str2, int[][] arr) { for (int i = 1; i <= str1.length(); i++) { for (int j = 1; j <= str2.length(); j++) { if (str1.charAt(i-1) == str2.charAt(j-1)) { arr[i][j] = arr[i - 1][j - 1] + 1; continue; } if (arr[i][j - 1] < arr[i - 1][j]) { arr[i][j] = arr[i - 1][j]; } else { arr[i][j] = arr[i][j - 1]; } } } } private static void showTheArr(String str1, int[][] arr) { int len = arr[0].length-1; System.out.print("最长公共子序列长度:"+arr[str1.length()][len]+"\t 它是: "); for(int i=1;i<arr.length;i++){ if(arr[i][len] >arr[i-1][len]){ System.out.print(str1.charAt(i-1)); } } System.out.println(); } private static int[][] initArr(String str1, String str2) { int len1 = str1.length()+1; int len2 = str2.length()+1; int[][] arr = new int[len1][len2]; for (int i = 0; i < len1; i++) { for (int j = 0; j < len2; j++) { arr[i][j] = 0; } } return arr; } private static void show(int[][] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j] + " "); } System.out.println(); } } }