-
了解KMP
要了解KMP算法主要要了解next数组的生成以及回溯位置的依据,这个还是很绕的,在写这个博客的时候都把自己绕进去好几回,所以建议看一遍有点迷糊的多看几遍,也可以在评论区一起讨论一下 -
图解KMP算法过程



-
next数组推导




/**
KMP算法next数组实现
next数据记载着模式串回溯的位置
*/
int * get_Next(char *model){
int *next;
int len = (int)strlen(model);
next = (int *)malloc(sizeof(int) * strlen(model));
if(len <= 0) return next;
//默认第0个位置的回溯位置为0
next[0] = -1;
for(int i = 1; i < len; i++){
if(i == 1){
//当i=1的前面只有一个字符所以直接将回溯位置置位0
next[i] = 0;
}else{
//否则找出前缀和后缀是否相等、有几个元素相等,对应求出回溯位置
if(model[i-1] == model[next[i-1]]){
next[i] = next[i-1] + 1;
}else{
next[i] = 0;
}
}
}
return next;
}
-
next数组优化



/**
next数组优化
*/
int * get_Next2(char *model){
int *next;
int len = (int)strlen(model);
next = (int *)malloc(sizeof(int) * strlen(model));
if(len <= 0) return next;
//默认第0个位置的回溯位置为0
next[0] = -1;
for(int i = 1; i < len; i++){
if(i == 1){
//当i=1的前面只有一个字符所以直接将回溯位置置位0
next[i] = 0;
}else{
//否则找出前缀和后缀是否相等、有几个元素相等,对应求出回溯位置
if(model[i-1] == model[next[i-1]]){
next[i] = next[i-1] + 1;
}else{
next[i] = 0;
}
}
}
for(int i = 1; i < len; i++){
//回溯位置优化
while (next[i] != -1 && model[i] == model[next[i]]) {
next[i] = next[next[i]];
}
}
return next;
}
-
代码实现
/**
KMP算法
*/
int kmp(char *str,char *model){
if(strlen(model) <= 0) return -1;
if(strlen(str) <= 0) return -1;
int *next = get_Next2(model);
int i = 0;
int j = 0;
while (i < strlen(str) && j < (int)strlen(model)) {
if(j == -1 || str[i] == model[j]){
i++;
j++;
}else{
j = next[j];
}
}
if(j >= (int)strlen(model)){
return i-j + 1;
}
return -1;
}