四 . 求串 T 的模式值 next[n] 的函数
 
说了这么多,是不是觉得求串 T 的模式值 next[n] 很复杂呢?要叫我写个函数出来,目前来说,我宁愿去登天。好在有现成的函数,当初发明 KMP 算法,写出这个函数的先辈,令我佩服得六体投地。我等后生小子,理解起来,都要反复琢磨。下面是这个函数 :
 
void get_nextval(const char *T, int next[])
 
{
 
// 求模式串 T 的 next 函数值并存入数组 next 。
 
int j = 0, k = -1;
 
next[0] = -1;
 
while ( T[j/*+1*/] != '\0' )
 
{
 
if (k == -1 || T[j] == T[k])
 
{
 
++j; ++k;
 
if (T[j]!=T[k])
 
next[j] = k;
 
else
 
next[j] = next[k];
 
}// if
 
else
 
k = next[k];
 
} // while
 
这里是我加的显示部分
 
// for(int i=0;i<j;i++)
 
//{
 
// cout<<next[i];
 
//}
 
//cout<<endl;
 
} // get_nextval
 
另一种写法,也差不多。
 
void getNext(const char* pattern,int next[])
 
{
 
next[0]= -1;
 
int k=-1,j=0;
 
while(pattern[j] != '\0')
 
{
 
if(k!= -1 && pattern[k]!= pattern[j] )
 
k=next[k];
 
++j;++k;
 
if(pattern[k]== pattern[j])
 
next[j]=next[k];
 
else
 
next[j]=k;
 
}
 
这里是我加的显示部分
 
// for(int i=0;i<j;i++)
 
//{
 
// cout<<next[i];
 
//}
 
//cout<<endl;
 
}
 
下面是 KMP 模式匹配程序,各位可以用他验证。记得加入上面的函数
 
#include <iostream.h>
 
#include <string.h>
 
int KMP(const char *Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。
 
{
 
if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )//
 
return -1;// 空指针或空串,返回 -1 。
 
int len=0;
 
const char * c=Pattern;
 
while(*c++!='\0')// 移动指针比移动下标快。
 
{
 
++len;// 字符串长度。
 
}
 
int *next=new int[len+1];
 
get_nextval(Pattern,next);// 求 Pattern 的 next 函数值
 
 
int index=0,i=0,j=0;
 
while(Text[i]!='\0' && Pattern[j]!='\0' )
 
{
 
if(Text[i]== Pattern[j])
 
{
 
++i;// 继续比较后继字符
 
++j;
 
}
 
else
 
{
 
index += j-next[j];
 
if(next[j]!=-1)
 
j=next[j];// 模式串向右移动
 
else
 
{
 
j=0;
 
++i;
 
}
 
}
 
}//while
 
 
delete []next;
 
if(Pattern[j]=='\0')
 
return index;// 匹配成功
 
else
 
return -1;
 
}
 
int main()//abCabCad
 
{
 
char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc";
 
char*pattern="adCadCad";
 
//getNext(pattern,n);
 
//get_nextval(pattern,n);
 
cout<<KMP(text,pattern)<<endl;
 
return 0;
 
}










