KMP----总结

图文请参考:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html

以下是我的理解。

首先要理解next数组的存在意义:减少子串的回溯-》如何减少?

构建next数组:首先数组第一位next[0]=-1;为什么是-1,其实它只是一个标识,表示现在已经是next数组的首位了,其实next[0]<0即可。

       先看代码(递推法):

 1 void getNext(char stringArray[],int next[])
 2 {
 3     next[0]=-1;//NEXT数组第一位设为-1; 
 4     int len=strlen(stringArray);
 5     
 6     int i=0,index=-1;
 7     //遍历子串得出NEXT数组 
 8     while(i<len)
 9     {
10         //当子串没有任何匹配时或者当前字符与前缀字符相同 
11         if(index==-1 ||stringArray[i]==stringArray[index])
12             next[++i]=++index;//得出下一位字符串的权值 
13         else
14             index=next[index];//失配时,前缀回到上一个前缀所保存的权值    
15     }
16     
17     //for(int i=0;i<len;i++)    printf("%d ",next[i]);//输出next数组 
18 }

首先要理解next数组的下一位的权值是由上一位权值所得出的。从代码可知:

可以构建next数组下一位的条件是当前前缀失配到-1,或者的当前字符与前缀表示的字符相同。而且当前缀是-1时,所构造的权值为0.

否则,就是失配,前缀会向前缀数组取权值index=next[index];

 

然后就是怎么使用next数组了,我对next数组的权值理解为失配的程度。

先看代码:

 1 int KMPMatch(char string[],char subString[])
 2 {
 3     int i=0,index=0,next[100];
 4     int len1=strlen(string),len2=strlen(subString);
 5     
 6     getNext(subString,next);//得到Next数组 
 7     
 8     //遍历字符串 
 9     while(i<len1)
10     {
11         //当子串时第一个字符或者子串的index位置字符与字符串的i位置字符匹配时 
12         if(index==-1 || string[i]==subString[index])
13         {
14             i++;//字符串位置移动 
15             index++;//子串位置移动 
16         }
17         //否则向next数组取权值 
18         else    index=next[index];
19         //当子串匹配完成时返回该位置 
20         if(index==len2)    return i-len2;
21     }
22 }

先看字符串能移动的条件:index=-1,也就是next数组首位时候,或者字符串的i位置的字符与子串index位置也就是失配位置(next的权值)相同
否则,也就是发生不匹配了,失配位置index=next[index]从next数组拿出失配程度

      

 

posted @ 2014-03-25 22:07  随心随想  阅读(149)  评论(0编辑  收藏  举报