动态规划+回溯法查找:两字符串的最长公共子序列LCS
测试
bdcaba
abcbdab
最长公共子序列长度:4
状态转移矩阵如下:
* * * * * * * *
* ^ \ < \ < < \
* ^ ^ ^ ^ \ < <
* ^ ^ \ < ^ ^ ^
* \ ^ ^ ^ ^ \ <
* ^ \ ^ \ < ^ \
* \ ^ ^ ^ ^ \ ^
最长公共子序列:b a d b
--------
abcbdab
bdcaba
最长公共子序列长度:4
状态转移矩阵如下:
* * * * * * *
* ^ ^ ^ \ < \
* \ < < ^ \ <
* ^ ^ \ < ^ ^
* \ ^ ^ ^ \ <
* ^ \ ^ ^ ^ ^
* ^ ^ ^ \ ^ \
* \ ^ ^ ^ \ ^
最长公共子序列:a b c b
(本题lcs是逆序输出的)import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
enum SrcDir {
SRC(-1, "源头格网", "*"),
UP(0, "数据源自上方格网", "^"),
LEFT(1, "数据源自左边格网", "<"),
LEFTUP(2, "数据源自左上方格网", "\\");
public int code;
public String msg;
public String dir;
SrcDir(int code, String msg, String dir) {
this.code = code;
this.msg = msg;
this.dir = dir;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str1 = scanner.nextLine();
String str2 = scanner.nextLine();
int len1 = str1.length();
int len2 = str2.length();
int[][] dp = new int[len1 + 1][len2 + 1];//动态规划矩阵
SrcDir[][] status = new SrcDir[len1 + 1][len2 + 1];//状态转移矩阵
for (int i = 0; i <= len1; i++) {
for (int j = 0; j <= len2; j++) {
//初始化
if (i == 0 || j == 0) {
dp[i][j] = 0;
status[i][j] = SrcDir.SRC;
} else {
//状态转移
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
status[i][j] = SrcDir.LEFTUP;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
status[i][j] = dp[i - 1][j] >= dp[i][j - 1] ? SrcDir.UP : SrcDir.LEFT;
}
}
}
}
//从右下角回溯到0行或者0列结束
int i = len1, j = len2;
List<Character> lcs = new ArrayList<>();
while (i > 0 && j > 0) {
if (status[i][j].code == 0) {
i--;
}
if (status[i][j].code == 1) {
j--;
}
if (status[i][j].code == 2) {
//回溯路径上的状态为LEFTUP(2, "数据源自左上方格网", "\\")的即为公共字符
lcs.add(str1.charAt(i - 1));
i--;
j--;
}
}
System.out.println("最长公共子序列长度:" + dp[len1][len2]);
System.out.println("状态转移矩阵如下:");
for (SrcDir[] val : status) {
for (SrcDir val1 : val) {
System.out.print(val1.dir + " ");
}
System.out.println();
}
System.out.print("最长公共子序列:");
for (char val : lcs) {
System.out.print(val + " ");
}
}
}
看网上到处是求lcs长度,没有找lcs的,就补了这个帖子😊
查看1道真题和解析