KMP算法的用来实现字符串匹配,时间复杂度为O(m+n)是典型的用空间换取时间的算法
算法的主要思想:
利用匹配串自自身的特点,每次产生不匹配的情况的时候,主串中的坐标不产生回溯,而是让匹配串去适应应该用目标串中哪个字符去匹配,然后记录下来,
其实,如果我们不去保存,完全可以通过程序每次去比对,(一个一个地比)只不过,我们能过数学的方式,通过计算,把这些所有的next[ ]给求出来,并记
录下来,这样程序执行的时候就不用去一个一个地去比对了,只要通过next数组就完全可以解决问题。
具体思路:
那我们应该如何求得,目标串(T)中每个下标对应的next[ ] 数组呢?
1.首先 规定 next[0]=-1; 而且 next[1]=0 是已知的。
2.我们用数学归纳法去解决这个问题:
当 j = next[i-1] 已知时,我们去求next[i] 换句话说我们想要去去next[i],可以根据next[i-1]去求得。
如何去求呢?我们的思路如下:
首先要理解要理解next数组的含义,k=next[i]数组表示匹配串中第i个字符和主串中的字符不匹配的时候,我们就让主串中的字符去和匹配串中的第k个字符去比较。至于和哪个去比较,为什么和它去比较就是我们要接下来要研究的问题
1.当T[ j ]== T[ i-1 ] 时这个时候next[ i ] = j+1;
2.当T[j] != T[ i-1 ]时,我们可以循环迭代,直到最后求出next
void getnext(char *tarstr,int next[])
{
int len=strlen(tarstr);
next[0]=-1;
for(int i=1;i<len;i++)
{
//issume we have know the next of (i-1) and now we want to get the next of i
//and we we want get the help next[i-1]
int j=next[i-1];
while(1)
{
if(-1==j)
{
next[i]=0;
break;
}
if(tarstr[i-1]==tarstr[j])
{
next[i]=j+1;
break;
}
else
{
j=next[j];
}
}
}
}
int KMP(char *mainstr,char *tarstr)
{
int next[20];
getnext(tarstr,next);
int minlen=strlen(mainstr);
int len=strlen(tarstr);
int i=0;
int j=0;
while(i<minlen&&j<len)
{
if(j==-1||mainstr[i]==tarstr[j])
{
i++;
j++;
}
else
{
j=next[j];
}
}
if(j==len)
return i-len;
else
return -1;
}