Java两个字符串的最长公共子串 KMP算法
1. 引言
在字符串处理中,经常需要找到两个字符串中的最长公共子串。最长公共子串是指在两个字符串中同时出现的最长的子串。比如,字符串 "ABCXYZ" 和 "XYZDEF" 的最长公共子串是 "XYZ"。
本篇文章将介绍如何使用KMP算法来解决这个问题。KMP算法是一种高效的字符串匹配算法,它的核心思想是避免不必要的比较,提高匹配效率。在解决最长公共子串问题时,我们可以利用KMP算法来找到两个字符串的公共子串。
2. KMP算法简介
KMP算法由三位计算机科学家D.E.Knuth、J.H.Morris和V.R.Pratt于1977年联合提出,它的全称是Knuth-Morris-Pratt算法。KMP算法通过预处理模式串(即匹配串)构建一个部分匹配表(Partial Match Table),然后利用这个表来快速定位模式串在目标串中的位置。
KMP算法的基本思想是,当遇到不匹配的字符时,不需要回溯,而是根据部分匹配表中的信息,将模式串向后移动一定的距离,继续匹配。这样可以避免在每次不匹配时,都从目标串的下一个字符开始重新匹配。
3. KMP算法在最长公共子串中的应用
KMP算法在最长公共子串问题中的应用相对简单。我们可以将其中一个字符串作为模式串,另一个字符串作为目标串,然后利用KMP算法来匹配模式串在目标串中的位置。
具体步骤如下:
- 构建模式串的部分匹配表。
- 遍历目标串,利用KMP算法匹配模式串在目标串中的位置。
- 根据匹配的位置,找到最长公共子串。
下面是使用Java实现的KMP算法的例子:
public class KMPAlgorithm {
public static String findLongestCommonSubstring(String str1, String str2) {
String pattern = str1;
String text = str2;
int[] table = buildTable(pattern);
int matchIndex = 0;
int longestSubstringLength = 0;
for (int i = 0; i < text.length(); i++) {
while (matchIndex > 0 && pattern.charAt(matchIndex) != text.charAt(i)) {
matchIndex = table[matchIndex - 1];
}
if (pattern.charAt(matchIndex) == text.charAt(i)) {
matchIndex++;
longestSubstringLength = Math.max(longestSubstringLength, matchIndex);
}
}
return str1.substring(0, longestSubstringLength);
}
private static int[] buildTable(String pattern) {
int[] table = new int[pattern.length()];
int prefixIndex = 0;
int suffixIndex = 1;
while (suffixIndex < pattern.length()) {
if (pattern.charAt(prefixIndex) == pattern.charAt(suffixIndex)) {
table[suffixIndex] = prefixIndex + 1;
prefixIndex++;
suffixIndex++;
} else if (prefixIndex > 0) {
prefixIndex = table[prefixIndex - 1];
} else {
table[suffixIndex] = 0;
suffixIndex++;
}
}
return table;
}
public static void main(String[] args) {
String str1 = "ABCXYZ";
String str2 = "XYZDEF";
String longestCommonSubstring = findLongestCommonSubstring(str1, str2);
System.out.println("Longest common substring: " + longestCommonSubstring);
}
}
4. 序列图
下面是使用mermaid语法绘制的KMP算法的序列图:
sequenceDiagram
participant Application
participant KMPAlgorithm
participant String
Application->>KMPAlgorithm: 调用findLongestCommonSubstring方法
KMPAlgorithm->>KMPAlgorithm: 构建模式串的部分匹配表
KMPAlgorithm->>KMPAlgorithm: 遍历目标串,匹配模式串
KMPAlgorithm->>String: 返回最长公共子串