我们首先需要搞清楚以下两个概念:最长公共子序列 VS 最长公共子串:
找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。
问题描述:
给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB,则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA
动态规划解法分析:
设 A=(A1,A2,…An) 和 B={B1,B2,…Bm} 是两个序列,将 A 和 B的最长公共子序列记为LCS(A,B)
找出LCS(A,B)就是一个最优化问题。因为,我们需要找到A 和 B中最长的那个公共子序列。而要找A 和 B的LCS,首先考虑A的最后一个元素和B的最后一个元素。
我们要求c[i] [j],先判断str1的第i个元素str2的第j个元素是否相同即判断str[i - 1]和 str[j -1]是否相同,如果相同它就是c[i - 1] [j- 1] +1,相当于在两个字符串都去掉一个字符时的最长公共子串再加 1;否则最长公共子串取c[i] [j-1]或c[i-1] [j]。
public class LCSequence {
//求解str1 和 str2 的最长公共子序列
public static int LCS(String str1, String str2) {
int[][] c = new int[str1.length() + 1][str2.length() + 1];
for (int row = 0; row <= str1.length(); row++)
c[row][0] = 0;
for (int column = 0; column <= str2.length(); column++)
c[0][column] = 0;
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))
c[i][j] = c[i - 1][j - 1] + 1;
else c[i][j] = c[i][j - 1] > c[i - 1][j] ? c[i][j - 1] : c[i - 1][j];
}
return c[str1.length()][str2.length()];
}
//test
public static void main(String[] args) {
String str1 = "BDCABA";
String str2 = "ABCBDAB";
int result = LCS(str1, str2);
System.out.println(result);
}
}
我们要求c[i] [j],先判断str1的第i个元素str2的第j个元素是否相同即判断str[i - 1]和 str[j -1]是否相同,如果相同它就是c[i - 1] [j- 1] +1,相当于在两个字符串都去掉一个字符时的最长公共子串再加 1;否则最长公共子串取0。
public class LongestSubstring {
//求解str1 和 str2 的最长公共子串
public static int findLongest(String str1, String str2) {
int[][] c = new int[str1.length() + 1][str2.length() + 1];
for (int row = 0; row <= str1.length(); row++)
c[row][0] = 0;
for (int column = 0; column <= str2.length(); column++)
c[0][column] = 0;
int res = 0;
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)){
c[i][j] = c[i - 1][j - 1] + 1;
res = Math.max(res, c[i][j]);
}
else c[i][j] = 0;
}
return res;
}
//test
public static void main(String[] args) {
String str1 = "HelloWorld";
String str2 = "loop";
int result = LCS(str1, str2);
System.out.println(result);
}
}
原文:https://www.cnblogs.com/susanhe/p/11565966.html