void getvoid GetNext(int next[],int length,char *s){
1
<em> </em>
void GetNext(char*s,int length,int next[])
{
next[0]=0;
int i=1,j=0;
1
<em>//首先我们初始化j等于零,其中,j表示的是模式串前缀的最后一个数的下标志,同时也表示前后缀相同的最大值,j表好似的是后缀的最后一个下标所指的位置</em>
for(i=1;i<length;i++){
while(j>0 && s[i]!=s[j]){
j=next[j-1]; //当其不相等的时候,用while循环回溯
}
if(s[i]==s[j]) //相等的时候j向前加
{
j++;
}
next[i]=j; //更新next数组,,主义,这里使用next[i]=j
}
}
int strStr(char* haystack, char* needle) {
int numssize1=strlen(haystack);
int numssize2=strlen(needle);//先得到模式串和目标川的长度
if(numssize2==0){
return 0;//若模式串的长度为零,返回零,符合c语言中的定义???
}
int next[numssize2];
int j=0,i=0;
GetNext(needle,numssize2, next);//初始化next数组
for(i=0;i<numssize1;i++)
{
while(j>0 && haystack[i]!=needle[j]){ //此时的i和j和上文的i,j表示的意思不同,初学者常犯的错误(当然也包括我)
j=next[j-1]; //若匹配不成功 则回溯,正是在这一步简化了运算,为何,因为既然数组下标能够加到j,说明其前面的几个数必然已经和目标串的前j个字符
//匹配成功了,那么这时i不动,我们只需要在比较第needle[next[j-1]+1]和haystack[i]即可,换句话说,
//此时重置了匹配进程,haystack中只有前next[j-1]个数被用到了,而不是向之前一样j个都被用到了,
//相反,此时若匹配失败的话,将会因为while循环不断回溯,一直到0时,将会(注意此时,j任然指向needle)
}
if(haystack[i]==needle[j]){
j++; //此时如匹配成功,j++
}
if(j==numssize2) //说明历经考研之后,j成功来到了了末尾,注意!此时j在最后一次时为j-1,相等后+1,即此时next[j]已经越界了,知识我们没有使用而已,此后如要
return (i-numssize2+1); //重新使用的话,还是得小心
//此时i已经指到对应位置+numssize的地方,又根据题意要求,我们加上1
}
return -1; //若经历了所有遍历后,函数没有在上一个出口返回,说明没有目标川中没有与模式串匹配的地方,那么,返回-1
}