kmp
a b a b h j j h a b a b c a b
i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
a b a b c
j 1 2 3 4 5
a b a b h j j h a b a b c a b
i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
a b a b c
j 0 1 2 3 4
i==4,j==4时不匹配,则改变j,j=next[j],
则此时比较的是 i==4,j==2;
代码:
// kmp
//
//
// a b a b h j j h a b a b c a b
//
//i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
//
// a b a b c
//
//j 1 2 3 4 5
//
//
//
// a b a b h j j h a b a b c a b
//
//i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
//
// a b a b c
//
//j 0 1 2 3 4
//
//i==4,j==4时不匹配,则改变j,j=next[j],
//
//则此时比较的是 i==4,j==2;
//代码:
#include <stdio.h>
#include<iostream>
using namespace std;
#include <string.h>
int next[32] = {-999};
//next 数组存的是以j结尾的字符串的前后缀 最长相同字符字符串的 数目
void get_next(string str1)
{
int i=-1,j=0;
next[j]=i;
while(j<str1.length() )
{
if(i!=-1&&str1[i]!=str1[j])
{
i=next[i];
}
else
{
next[++j]=++i;
}
}
}
int kmp(char *str1,char *str2)
{
int i,j;
i = j = 0;
while(i < strlen(str1)&&j<strlen(str2))
{
while(j!=-1&&str1[i]!=str2[j])//当不匹配时,
{
j = next[j];
}
i++;
j++;
}
if(j == strlen(str2))
return i-j;
return -1;
}
int kmp1(char *str1,char *str2)
{
int i=0,j=0,ans=0;
while (i<strlen(str1))
{
if (str1[i]==str2[j] || j==-1)
{
i++;
j++;
}
else j=next[j];
if (j==strlen(str2))//如果匹配成功,则视作这次匹配失败,返回到上一次。
{
ans++;
j=next[j-1];
i--;
}
}
return ans;
}
int main(void)
{
char s[100] ;//短
char t[100] ; //长
cin>>s>>t;
int pos = 0;
int index;
printf("================ KMP ==============\n");
get_next(s);
index = kmp(t, s);
printf("index = %d\n", index);
printf("index = %d\n", kmp1(t,s));
}