最长公共子序列-LCS
记住这个公式,基本就OK了。
代码版本一:仅仅输出最长子序列的个数
import java.util.Scanner; /** * Created by jacob on 2019-07-24. */ public class Main { public static void main(String[] args) { Main main = new Main(); Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { String[] strings = scanner.nextLine().split(" "); System.out.println(main.longestCommonSequence(strings[0], strings[1])); } } private int longestCommonSequence(String a, String b) { if (a.length() == 0 || b.length() == 0) { return 0; } int[][] dp = new int[a.length() + 1][b.length() + 1]; char[] aChars = a.toCharArray(); char[] bChars = b.toCharArray(); for (int i = 0; i < a.length(); i++) { for (int j = 0; j < b.length(); j++) { if (aChars[i] == bChars[j]) { dp[i + 1][j + 1] = dp[i][j] + 1; } else { dp[i + 1][j + 1] = Math.max(dp[i][j + 1], dp[i + 1][j]); } } } return dp[a.length()][b.length()]; } }
代码版本2: 同时也输出所有可能的序列
import java.util.HashSet; import java.util.Scanner; import java.util.Set; /** * Created by jacob on 2019-07-24. */ public class Main { public static void main(String[] args) { Main main = new Main(); Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { String[] strings = scanner.nextLine().split(" "); System.out.println(main.longestCommonSequence(strings[0], strings[1])); } } private Set<String> longestCommonSequence(String a, String b) { if (a.length() == 0 || b.length() == 0) { return null; } int[][] dp = new int[a.length() + 1][b.length() + 1]; char[] aChars = a.toCharArray(); char[] bChars = b.toCharArray(); for (int i = 0; i < a.length(); i++) { for (int j = 0; j < b.length(); j++) { if (aChars[i] == bChars[j]) { dp[i + 1][j + 1] = dp[i][j] + 1; } else { dp[i + 1][j + 1] = Math.max(dp[i][j + 1], dp[i + 1][j]); } } } // 将二维数组的数据全部填充完毕 Set<String> result = new HashSet<>(); this.printCommonSequeue(aChars, bChars, dp, "", result, a.length(), b.length()); return result; } private void printCommonSequeue(char[] aChars, char[] bChars, int[][] dp, String initStr, Set<String> result, int i, int j) { StringBuilder stringBuilder = new StringBuilder(initStr); while (i > 0 && j > 0) { if (aChars[i - 1] == bChars[j - 1]) { stringBuilder.append(aChars[i - 1]); i--; j--; } else { if (dp[i][j - 1] > dp[i - 1][j]) { j--; } else if (dp[i][j - 1] < dp[i - 1][j]) { i--; } else { this.printCommonSequeue(aChars, bChars, dp, stringBuilder.toString(), result, i - 1, j); j--; } } } result.add(stringBuilder.reverse().toString()); } }
作者博客:www.cnblogs.com/coderbean/