/*
2012-7-10,字符串的模式匹配:KMP算法
*/
#include <stdio.h>
char string[]="acabaababaabcacaabc";
char mod[]="abaabc";
int next[10]={0};
//通过模式串来计算得到next数组,里面记录的是在某个字符失配的时候从第几个重新开始
void GetNext(char*str,int next[])
{
int i,j;
int size;
size=strlen(str);
i=1;
j=0;
next[1]=0;
while(i<size)
{
if( j==0 || str[j-1]==str[i-1])
{
j++;
i++;
next[i]=j;
}
else
{
j=next[j];
}
}
}
//上面算法的改进,如果模式串的前面有连续相同的他们的重载点还是一样的,
void GetNext2(char*str,int next[])
{
int i,j;
int size;
size=strlen(str);
i=1;
j=0;
next[1]=0;
while(i<size)
{
if( j==0 || str[j-1]==str[i-1])
{
j++;
i++;
if(str[j]!=str[i])
next[i]=j;
else
next[i]=next[j];
}
else
{
j=next[j];
}
}
}
void PrintNext(int size)
{
int i=0;
printf("%s\n%s\n",string,mod);
while(i<size+1)
{
printf("%c ",mod[i++]);
}
printf("\n");
i=1;
while(i<size+1)
{
printf("%d ",next[i++]);
}
printf("\n");
}
int KMP_search(char * src,char*mod,int pos)
{
int srclen,modlen,i,j;
srclen=strlen(src);
modlen=strlen(mod);
i=j=0;
i=pos;
while(j<modlen&&i<srclen)
{
if(j!=-1)
printf("i=%d j=%d,%c===%c\n",i,j,src[i],mod[j]);
if( j==-1 || src[i]==mod[j] )
{
j++;
i++;
}
else
{
j=next[j+1]-1;
}
}
if(j>=modlen)
{
printf("Find Mod in string at pos = %d\n",i-j);
return i-modlen;
}
else
return 0;
}
void main()
{
/*要匹配的串和模式串分辨是string 和mod两个字符串数组*/
GetNext2(mod,next);
PrintNext(strlen(mod));
KMP_search(string,mod,0);
}