模式匹配之KMP算法的理解(二)

        昨天说到了有公式 "p1p2.......p(k-1)"= “p(j-k+1)p(j-k+2).......p(j-1)”. 观察下该公式,这个等式是在模式串中存在的。很显然接下来的工作主要就是在模式串中找到这样的等式。模式串P中的pj(即模式串中的第j个字符)与主串中的Si不匹配的时候,将比较Si与模式串P中第k个pk字符比较。定义一个数组next[0......j-1].这个数组的值next[j-1]=k表示模式串P中第j个字符的与主串字符Si不匹配时应该将模式串移动的位置pk与Si继续比较。
      根据这么分析的话,就可以得出KMP的算法如下:
      typedef struct
    {
        char ch[MaxSize];
        int len;                               //串长
     }SqString;


     int KMPIndex(SqString s,SqString t)
    {
            int next[MaxSize],i = 0 , j = 0, m;
            GetNext(t,next);                   //获取next数组

        while(i < s.len&& j < t.len)
            {
                if(j == -1 || s.ch[i] == t.ch[j])
                {
                    i++;
                    j++;
                }
                else
                   j = next[j];
           }
            if(j >=t.len)
                m = i-t.len;
            else
                m =-1;
         return m;
    }        

下面说明next数组过程,next的定义如下:

next[j]= max{k|0<k<j,且
"p1p2.......p(k-1)"= “p(j-k+1)p(j-k+2).......p(j-1) "} 此集合非空时
          = -1 当 j = 0 时
          = 0 其他情况

根据该定义  依次求next[j]的值。
        定义next[0] =-1
        next[j] = k;根据next[j] =k可以得出
p1p2.......p(k-1)"= “p(j-k+1)p(j-k+2).......p(j-1),那么现在计算next[j+1].当pk=pj时,则有next[j+1] = k +1 =next[j]+1;而当 pk!=pj时, p1p2.......p(k-1)pk"!= “p(j-k+1)p(j-k+2).......p(j-1)pj。那么此时pk不匹配。则应该移动到next[k]处。如果继续不匹配,则直至next[k] = 0
       next数组的求法如下:
       void GetNext(SqString t, int next[])
    {
        int j,k;
        j =0 ;
        k= -1 ;
        next[0] =-1;
        while(j < t.len -1)
        {
        if(k == -1||t.ch[j] == t.ch[k])
        {
            j++;
            k++;
            next[j] = k;
        }
        else
            k =next [k];
    }
}
    
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值