coderLucas

Miracles happen every day.

线性表-串:KMP模式匹配算法

一、简单模式匹配算法(略,逐字符比较即可)

二、KMP模式匹配算法

next数组:j为字符序号,从1开始。

(1)当j=1时,next=0;

(2)当存在前缀=后缀情况,next=相同字符数+1;

(3)当前缀 != 后缀且j != 1时,next=1。

如下:

  abcdex  

next=011111

          abcabx

next=011123

          ababaaaba

next=011234223

说明:0位置为情况1;

        1、2位置为情况3;

        3-5位置一直有前缀对称,所以一直累加;

        6位置前缀不对称,j=next[ j ]找对称子串开始位置;如果没有继续j= next[ j ]直到 j = 0,next为0;

                 此处 i = 6, j = 4;第一次找: j = next[4] = 3, T[3] != T[6] ,没找到;第二次找: j= next[ 3 ] =1, T[2] == T[6], 找到累加 j+1 =2;

        7位置同上;

        8位置在7位置基础累加得到。

          aaaaaaaab

next=012345678

说明:0位置为情况1;

    1位置为情况3;

            2-8位置一直有前缀对称,所以一直累加。

代码如下:

  1: void get_next(char T[], int * next)  
  2: {  
  3: int i = 1;  
  4: int j = 0;  
  5: 
  6:     next[1] = 0;//条件(1)
  7: 
  8: while(i < getlength(T))  
  9:     {  
 10: if(j == 0 || T[i] == T[j])  
 11:         {  
 12:             ++j;  
 13:             ++i;  
 14:             next[i] = j;//如果前缀一直有对称,则对称性累加
 15:         }  
 16: else
 17:         {  
 18:             j = next[j];//如果前缀不对称,则从对称性开始的地方开始累加;
 19: //如果仍然不对称,则继续从子子对称开始的地方开始累加;
 20:         }  
 21:     }  
 22: }  
 23: 

 

三、KMP模式匹配算法改进

nextval数组:j为字符序号,从1开始。

(1)当j=1时,nextval=0;

(2)当存在前缀=后缀情况,nextval=相同字符数+1如果该字符在后缀中,则nextval = 前缀中该字符的nextval值。

(3)当前缀 != 后缀且j != 1时,nextval=1。

如下:

               ababaaaba 

next=     011234223

nextval=010104210

               aaaaaaaab 

next=     012345678

nextval=000000008

               ababaaaba 

next=     011234223

nextval=010104210

代码如下:

  1: void get_nextval(char T[], int * nextval)  
  2: {  
  3: int i = 1;  
  4: int j = 0;  
  5: 
  6: nextval[1] = 0;//条件(1)
  7: 
  8: while(i < getlength(T))  
  9: {  
 10:   if(j == 0 || T[i] == T[j])  
 11:   {  
 12:             ++j;  
 13:             ++i;  
 14:             if(T[i] != T[j])   
 15:               nextval[i] = j;//条件(3),累加
 16:             else
 17:               nextval[i] = nextval[j];//条件(2)</strong>
 18:   }  
 19:   else
 20:   {  
 21:             j = nextval[j];//如果前缀不对称,则从对称性开始的地方开始累加;
 22:                            //如果仍然不对称,则继续从子子对称开始的地方开始累加;
 23:   }  
 24: }  
 25: 
 26: }  
 27: 
posted @ 2014-05-06 11:26  lucas hsueh  阅读(251)  评论(0编辑  收藏  举报