kmp算法相对于BF算法是不要回溯 , 不需要回溯 , 是因为在匹配过程中 , 不移动匹配串只移动模式串。
在求解next数组时 , 下面使用了两种方法。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
char s[1000000]; //被匹配字符串
char t[100000]; //匹配字符串
int next[100000]; //存储匹配串中每个字符应移的距离
int s_length , t_length;//被匹配串和匹配串的字符长度
/*void getnext(void)
{
int i=0,j=-1;
next[0]=-1;
while(i<t_length)
{
if(j==-1||t[i]==t[j])
{
i++;//如果i=len-1,执行这步会使next[len]存在
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}*/
void getnext()
{
int i = 0, j =-1;
next[i] = -1;
while(i <= t_length)
{
while(j >= 0 && t[i] != t[j]) j = next[j]; //和该字符前面的字符比较 , 看是否和前面的字符相同
i++; j++;
if(t[i] == t[j]) next[i] = next[j];//如果当前两字符相同 ,
else next[i] = j;
}
}
//向右滑动的距离为:j-next[j]
int main()
{
int case1;
scanf("%d" , &case1);
while(case1--)
{
int i , j , sum = 0;
scanf("%s" , t);
scanf("%s" , s);
s_length = strlen(s);
t_length = strlen(t);
if(s_length < t_length)
{
printf("0\n");
continue;
}
getnext();
for(i = 0; i <= t_length; i++)
printf("%d " , next[i]);
cout<<endl;
i = 0 , j = 0;
while(j < s_length)
{
//int z = j;
while(i == -1 || (i < t_length && s[j] == t[i])) j++ , i++;
if(i >= t_length)
{
// printf("%d\n" , j);
sum += 1;
}
i = next[i];
}
cout<<sum<<endl;
}
return 0;
}