什么是最长公共子字符串算法? 举一个例子就清楚了
比如我们有两个字符串:
Please, peter go swimming!
I’m peter goliswi
那么该算法应该输出’peter go’. 最长公共子字符串算法通过suffix trees算法 (时间复杂度O(n),但是实现极其复杂) 可以获得效率很高的实现。但是在本帖中我们要使用效率稍次的‘动态编程’思想来实现该算法。动态编程,顾名思义, 就是重用前一步已经计算出来的信息。要理解这种实现,我们首先需要填写一个二维的整数型数组,假如我们用i表示水平方向的字符串(Please, peter go swimming!),以j表示垂直方向的字符串(I’m peter goliswi) 如图:
please, peter go swimming
i 0000000000000000000100100
' 0000000000000000000000000
m 0000000000000000000011000
0000000100000100100000000
p 1000000020000000000000000
e 0010010003000000000000000
t 0000000000400000000000000
e 0010010001050000000000000
r 0000000000006000000000000
0000000100000700100000000
g 0000000000000080000000000
o 0000000000000009000000000
l 0100000000000000000000000
i 0000000000000000000100100
s 0001000000000000010000000
w 0000000000000000002000000
i 0000000000000000000300100
当i=19 j=0时我们得到第一个相等的字符‘i’,这时把相应的index对应的数组值设为1;
依此类推继续填表;
当 i= 8 j= 4时我们得到另一个相等的字符’ ’(空格),现在我们要重用前一步的计算结果(num[7][3]=1)
所以num[8][4] = 1 + num[7][3]就应该是2.这样我们就得到了一个长度为2的相等子字符串;
以此规则填完这个动态表;
下面是一段参考实现
public static String longestSubstring(String str1, String str2) {
StringBuilder sb = new StringBuilder();
if (str1 == null || str1.isEmpty() || str2 == null || str2.isEmpty())
return "";
// ignore case
str1 = str1.toLowerCase();
str2 = str2.toLowerCase();
// java initializes them already with 0
int[][] num = new int[str1.length()][str2.length()];
int maxlen = 0;
int lastSubsBegin = 0;
for (int i = 0; i < str1.length(); i++) {
for (int j = 0; j < str2.length(); j++) {
if (str1.charAt(i) == str2.charAt(j)) {
if ((i == 0) || (j == 0))
num[i][j] = 1;
else
num[i][j] = 1 + num[i - 1][j - 1];
if (num[i][j] > maxlen) {
maxlen = num[i][j];
// generate substring from str1 => i
int thisSubsBegin = i - num[i][j] + 1;
if (lastSubsBegin == thisSubsBegin) {
//if the current LCS is the same as the last time this block ran
sb.append(str1.charAt(i));
} else {
//this block resets the string builder if a different LCS is found
lastSubsBegin = thisSubsBegin;
sb = new StringBuilder();
sb.append(str1.substring(lastSubsBegin, i + 1));
}
}
}
}}
return sb.toString();
}
分享到:
相关推荐
Java中的动态规划法被广泛应用于解决复杂的问题,如求解最长公共子序列(Longest Common Subsequence, LCS)和最长公共子字符串(Longest Common Substring, LSS)。这两个概念在计算机科学中尤其是在字符串处理和...
最长公共子序列(Longest Common Subsequence,LCS)算法是一种经典的计算机科学问题,主要应用于比较和分析两个或多个序列的相似性。在文本编辑、生物信息学、数据挖掘等领域有着广泛的应用。LCS问题的基本目标是...
java-string-similarity, 各种字符串相似性和距离算法 java-string-similarity 实现不同字符串相似度和距离度量的库。 目前已经实现了许多算法( 包括Levenshtein编辑距离和 sibblings,jaro winkler,最长公共子序列...
总结起来,这个Java项目提供了计算两个字符串相似度的方法,主要利用了最长公共子序列的概念和动态规划算法。通过理解并实现这个项目,开发者可以增强对字符串处理、动态规划以及相似度计算的理解,这对进行文本分析...
最长公共子序列(Longest Common Subsequence,简称LCS)是计算机科学中一种经典的问题,主要出现在序列比对、文本编辑距离等领域。在两个给定的字符串中,LCS是指不考虑字符顺序的最长子串,它同时存在于这两个字符...
在编程领域,字符串处理是常见的任务之...总之,理解和实现寻找字符串最长回文子串的算法对提升编程技能非常有帮助,无论是动态规划的思路还是Manacher's Algorithm的巧妙设计,都能加深对字符串处理和算法优化的理解。
通过上述分析,我们可以看到,这段程序实现了对两个字符串的最长公共子串的有效计算。尽管其实现方式相对简单,但对于理解和学习动态规划的基本思想具有很好的参考价值。此外,在实际应用中,还可以考虑使用更高效的...
Shingles (n-gram) 的相似度和距离莱文斯坦规范化编辑加权编辑达梅劳-莱文斯坦最佳字符串对齐贾罗-温克勒最长公共子序列度量最长公共子序列N 元语法基于 Shingle (n-gram) 的算法Q-Gram余弦相似度杰卡德指数Sorensen...
给定两个字符串S和T,一个公共子序列是同时存在于这两个字符串中的一个序列,而最长公共子序列是这些子序列中长度最长的一个。注意,LCS不一定要连续,也不需要是原字符串的子串。 **算法概述:** LCS问题可以通过...
这是指KMP算法的主要应用,即判断一个给定的子串是否是主字符串的子序列。通过遍历主字符串和子串,如果可以顺利完成匹配,那么子串就在主字符串中;反之,不在。 4. 描述中的"2是检索出现几次": 如果我们要统计...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中的一种经典问题,尤其在算法和数据结构领域有着广泛的应用。这个问题涉及到比较两个序列,找出它们的最长的子序列,这个子序列不需要在原序列中...
五、字符串算法 1. KMP算法:用于字符串匹配,避免了不必要的回溯。 2. Rabin-Karp算法:通过滚动哈希值快速查找子串。 3. Boyer-Moore算法:利用坏字符规则和好后缀规则提高匹配效率。 六、数据结构 1. 树:...
总结来说,解决"java求字符串的正向反向最大公共字符串"这个问题,我们可以采用动态规划方法,通过对字符串的遍历和比较,找出并返回最长的公共子串。这种技术在处理字符串匹配、编辑距离等问题时非常常见,有助于...
【最长公共子序列】(Longest Common Subsequence, LCS) 是一种在计算机科学中常见的字符串比较问题,主要涉及序列和动态规划。这个问题的目标是找到两个给定字符串的最长子序列,这个子序列不必连续,但必须保持原...
4. **动态规划**:动态规划是解决复杂问题的有效方法,如背包问题、最长公共子序列、斐波那契数列等。理解动态规划的核心思想——记忆化和状态转移,对优化问题求解至关重要。 5. **回溯法**:主要用于解决组合优化...
最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和算法设计。在两个或多个字符串中找到一个最长的子序列,这个子序列不必连续,但必须保持原顺序。例如,...
6. 字符串处理:如KMP算法、Rabin-Karp算法,用于字符串匹配和模式查找。 7. 数学算法:如大整数运算、素数检测、矩阵运算等,对于加密算法、数学计算软件等有重要应用。 8. 计数和概率算法:如哈希表计数、斯特林...
最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和算法设计。在两个或多个字符串中找到最长的序列,该序列不一定是连续的,但存在于每个字符串中,这就是LCS...