数据结构上虽然有该算法大概的实现,但是字符串并不是C的字符串,Terry R. McConnell也写过一个,但是在next数组中,我认为有问题,所以我自己写了一个kmp查找子串,C的字符串风格
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void set_next(const char* substr,int* next)
{
int k,i;
if(strlen(substr)==1){
next[0]= 0 ;
return;
}
next[0] = 0;
next[1] = 0;
for(i=1,k=0;i<(strlen(substr)-1);i++){
while(k&&(substr[k]!=substr[i]))
k = next[k];
if(substr[k]==substr[i]){
k++;
next[i+1] = k; /*set the next element's next!!*/
}else{
next[i+1] = 0; /*set the next element's next*/
}
}
}
const char* mstrstr(const char* str,const char* substr)
{
int* next ;
int i=0,j=0;
const char* ret = NULL;
assert(str&&substr);
next = (int*)malloc(sizeof(int)*strlen(substr));
set_next(substr,next);
while(i<strlen(str)){
if(str[i]==substr[j]){
j++;
i++;
if(j==strlen(substr)){
ret = str -j + i;
goto end;
}
}else{
if(j==0){
i++;
}else{
int tmp = j;
j= next[j];
printf("from %d[%c] to %d[%c] when compare %d[%c] with %d[%c]/n",
tmp,substr[tmp],j,substr[j],
tmp,substr[tmp],i,str[i]);
}
}
}
end:
free(next);
return NULL;
}
int main(int argc,char ** argv)
{
int* next;
int i;
if(argc!=3)return;
next = malloc(sizeof(int)*strlen(argv[2]));
set_next(argv[2],next);
for(i = 0;i<strlen(argv[2]);i++)
printf(" %d",next[i]);
free(next);
mstrstr(argv[1],argv[2]);
}