一、KMP算法介绍
参考:详尽的KMP算法介绍
二、代码实现
2.1 暴力匹配算法解决字符串包含问题
import java.util.jar.JarEntry;
public class ViolenceMatch {
public static void main(String[] args) {
String str1 = "abcdefabcghijklmn";
String str2 = "abcg";
int index = violenceMatch(str1,str2);
System.out.println("index =" + index);
}
//暴力匹配算法
public static int violenceMatch(String str1,String str2){
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
int s1len = s1.length;
int s2len = s2.length;
int i = 0;
int j = 0;
while(i < s1len && j < s2len){
if(s1[i] == s2[j]){
i++;
j++;
}else{
i = i - (j - 1);
j = 0;
}
}
if(j == s2len){
return i - j;
}else{
return -1;
}
}
}
2.2 KMP算法解决字符串包含问题
import java.util.Arrays;
public class KMPAlgorithm {
public static void main(String[] args) {
String str1 = "BBC ABCDAB ABCDABCDABDE";
String str2 = "ABCDABD";
int[] next = kmpNext("ABCDABD");
System.out.println(Arrays.toString(next));
int index = kmpSearch(str1,str2,next);
System.out.println("Index = " + index);
}
//KMP算法求解字符串匹配问题
//1.先获取到长度较小的字符串的部分匹配值
public static int[] kmpNext(String dest){
int[] next = new int[dest.length()];
next[0] = 0; //如果字符串长度为1,那么对应的部分匹配值为0
for (int i = 1,j = 0; i < dest.length(); i++) {
//没有这个函数,输出为[0, 0, 0, 0, 1, 2, 2],最后一个数字不对
while(j > 0 && dest.charAt(i) != dest.charAt(j)){
j = next[j - 1];
}
if(dest.charAt(i) == dest.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}
//2.KMP搜索算法
public static int kmpSearch(String str1,String str2,int[] next){
for (int i = 0,j = 0; i < str1.length(); i++) {
while(j > 0 && str1.charAt(i) != str2.charAt(j)){
j = next[j - 1];
}
if(str1.charAt(i) == str2.charAt(j)){
j++;
}
if(j == str2.length()) {
return i - j + 1;
}
}
return -1;
}
}
三、测试结果
3.1 暴力匹配法测试结果
index =6
3.2 KMP算法测试结果
[0, 0, 0, 0, 1, 2, 0]
Index = 15
注意点:
1.注意KMP算法的核心原理
2.注意暴力匹配算法最后return i - j;而KMP算法最后return i - j + 1的区别,原因就在于暴力匹配算法i与j同时递增,而KMP算法先j递增,后i递增,最后一次循环j递增后,满足条件退出循环,此时i未递增