KMP算法
KMP核心思路
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。
换言之,当匹配失败时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值,即移动的实际位数为:j - next[j],且此值大于等于1。
下面展示一些 KMP的核心代码
。
/**
* kmp 搜索算法
* @param str1 原始数组
* @param str2 查找串
* @param next 部分匹配表
* @return 如果是-1 就是没有匹配到,否则返回第一个匹配的位置
*/
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];//KMP算法的核心,此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位
//相当于j 移动到 前面已经确定是匹配的 位置
//但是i不用动
}
if(str1.charAt(i) == str2.charAt(j)){
j++;
}
if(j == str2.length()){
return i - j + 1;//当前比较的位置,减去 模式串的长度 + 1;
}
}
return -1;
}
public static int[] kmpNext(String dest){
int next[] = new int[dest.length()];
next[0] = 0;
for (int i = 1,j = 0; i < next.length; i++) {
//一开始j = 0 , 且没有一个字符是相同的时候,只有i动,j不动。
//直到找到第一个与dest.charAt(j) 相同时 , j才开始动,且记录当前i位置上的 j ,j是前缀和后缀重合的个数。
while(j > 0 && dest.charAt(i) != dest.charAt(j)){
//当有字符不同的时候,且j > 0,则回到上一个位置(跳过已经匹配过的),继续移动i,进行比较
j = next[j-1];
}
if(dest.charAt(i) == dest.charAt(j) ){
j++;
}
next[i] = j;
}
return next;
}
参考链接:https://www.cnblogs.com/zzuuoo666/p/9028287.html