最长公共子序列:给定两个字符串,求二者公共子序列的最长长度。
按照序列的长度来划分状态(dp),也就是 s1的前 i 个字符和 s2 的前 j 个字符 的最长公共子序列长度,记为lcs[i][j].
如果 s1 的第 i 项和 s2 的第 j 项相同,那么 s1[i] 与 s2[j] 作为公共子序列的末尾,则
如果 s1的第 i 项和 s2 的第 j 项不相同,那么就看 lcs[i-1][j] 和 lcs[i][j-1] 谁大,
这篇博客很好https://www.cnblogs.com/handsomecui/p/4717444.html。
代码如下:
package Texun_12;
import java.util.Scanner;
public class L18 {
static int[][] dp = new int[110][110];
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String a = sc.next();
String b = sc.next();
int lena = a.length();
int lenb = b.length();
for (int i = 1; i <= lena; i++) {
for (int j = 1; j <= lenb; j++) {
if (a.charAt(i - 1) == b.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}else {
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
}
}
}
System.out.println(dp[lena][lenb]);
}
}
无脑:写
package L6;
import java.util.Arrays;
public class _LCS {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1 = "asdf";
String s2 = "dfg";
LCS(s1, s2);
}
private static void LCS(String s1, String s2) {
// TODO Auto-generated method stub
int len1 = s1.length();
int len2 = s2.length();
int[][] dp = new int[len1 + 1][len2 + 1];
int flag = 0;
// 初始化第一列
for (int i = 1; i <= len1; i++) {
if (flag == 1) {
dp[i][1] = 1;
} else if (s1.charAt(i - 1) == s2.charAt(0)) {
dp[i][1] = 1;
flag = 1;
} else {
dp[i][1] = 0;
}
}
// 初始化第一行
flag = 0;
for (int j = 1; j <= len2; j++) {
if (flag == 1) {
dp[1][j] = 1;
} else if (s1.charAt(0) == s2.charAt(j - 1)) {
dp[1][j] = 1;
flag = 1;
} else {
dp[1][j] = 0;
}
}
// 打表
for (int i = 2; i <= len1; i++) {
for (int j = 2; j <= len2; j++) {
int max = Math.max(dp[i - 1][j], dp[i][j - 1]);
if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = Math.max(max, dp[i - 1][j - 1] + 1);
} else {
dp[i][j] = max;
}
}
}
System.out.println(dp[len1][len2]);
}
}