next数组的生成
1.next数组的内容
next[i]表示模板字符串从下标为i-1处之前的字符串的最长公共前后缀的长度。
2.next数组的作用
如果搜索过程中发现此时不匹配,此时指向母串的下标是i,指向模板字符串的下标是j,那么此时next[i]就表示模板字符串中前next[i]个字符已经不需要验证,所以直接将模板字符串的第i+1个字符和母串的第i个字符开始比较。
void getNext(){
//str1表示模板字符串
int pLen = strlen(str1);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
if (k == -1 || str1[j] == str1[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
搜索函数
1.和暴力搜索法的区别
暴力法有回溯,但kmp算法不需要回溯母串,这便是这个算法的优势之处,而不需要回溯的原因就是它充分利用已经遍历过的字符串的信息。
int kmpSearch(){
int i = 0;
int j = 0;
int sLen = strlen(str);
int pLen = strlen(str1);
while (i < sLen && j < pLen)
{
if (j == -1 || str[i] == str1[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
整个过程
#include<stdio.h>
#include<string.h>
#define MAX 1000
int next[MAX]={0};
char str[MAX];
char str1[MAX];
void getNext(){
int pLen = strlen(str1);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
if (k == -1 || str1[j] == str1[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
int kmpSearch(){
int i = 0;
int j = 0;
int sLen = strlen(str);
int pLen = strlen(str1);
while (i < sLen && j < pLen)
{
if (j == -1 || str[i] == str1[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
int main(){
scanf("%s",&str);
scanf("%s",&str1);
getNext();
int index=kmpSearch();
printf("%d",index);
return 0;
}
示例输入:
aaabbcabbdcaaabcd
bbd
输出:7