基本思想
求next数组
时间复杂度:O(m+n)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//朴素查找算法
//在主串str中查找子串sub
int BF(const char *str,const char *sub,int pos)//O(n*m)
{
int lenstr = strlen(str);
int lensub = strlen(sub);
if(pos<0 || pos>lenstr)
{
return -1;
}
int i = pos;
int j = 0;
while(i<lenstr && j<lensub)
{
if(str[i] == sub[j])
{
i++;
j++;
}
else
{
i = i-j+1;//i需要回退
j = 0;//j总是退到0
}
}
if(j >= lensub)//找到了
{
return i-j;
}
else
{
return -1;
}
}
//todo GetNextVal();
static void GetNext(const char *sub,int *next)
{
int lensub = strlen(sub);
next[0] = -1;
next[1] = 0;//next[j] = k;
int j = 1;
int k = 0;
while(j+1 < lensub)
{
if(k==-1 || sub[k]==sub[j])//Pk = Pj
{
next[++j] = ++k;
/*next[j+1] = k+1;
j++;
k++;*/
}
else
{
k = next[k];//k=next[j];
}
}
}
int KMP(const char *str,const char *sub,int pos)//1、i不回退,2、O(n+m)
{
int lenstr = strlen(str);
int lensub = strlen(sub);
int i = pos;
int j = 0;
int *next = (int *)malloc(lensub*sizeof(int));
GetNext(sub,next);
while(i<lenstr && j<lensub)
{
if((j==-1) || (str[i]==sub[j]))
{
i++;
j++;
}
else
{
//i不回退
j = next[j];//KMP
}
}
free(next);
if(j >= lensub)
{
return i-j;
}
else
{
return -1;
}
}
int main()
{
char *str = "ababcabcdabcde";
char *sub = "abcd";
printf("%d\n",KMP(str,sub,10));
return 0;
}