KMP模式匹配

 

自己的机子上用DEVC尽然出现异常在别人机子上没事,郁闷死,弄了超久才弄出来,汗,有空一会出个解题报告

 

  1. #include<iostream>
  2. #include<string>
  3. #include<malloc.h>
  4. #include<stdlib.h>
  5. using namespace std;
  6. int *nextval;
  7. void get_nextval(string s,int *next)
  8. {
  9.      next[0]=-1;
  10.      int j=0,i=-1,s_len=s.size();
  11.      while(j<s_len)
  12.      {
  13.       if(i==-1||s[j]==s[i]) {
  14.        i++;
  15.        j++;
  16.        if(s[j]!=s[i]) 
  17.                       next[j]=i;
  18.        else 
  19.                       next[j]=next[i];
  20.        }
  21.       else 
  22.            i=next[i]; }
  23. }
  24. int Index_KMP(string s,string t,int pos)
  25. {
  26.     int i=pos-1,j=0,s_len=s.size(),t_len=t.size();
  27.     while(i<s_len&&j<t_len)
  28.     {if(j==-1||s[i]==t[j]) {++i;++j;}
  29.      else j=nextval[j];
  30.     }
  31.     if(j==t_len) return i-t_len+1;
  32.     else return 0;} 
  33. int main()
  34. {
  35.    string s,t;
  36.    while(cin>>s>>t)
  37.    {
  38.    nextval=(int*)malloc(t.size()*sizeof(int));
  39.    get_nextval(t,nextval);
  40.    for(size_t i=0;i<t.size();i++)
  41.    cout<<nextval[i]<<" ";
  42.    cout<<endl;
  43.    cout<<Index_KMP(s,t,1)<<endl;
  44.    free(nextval);
  45.    }
  46.    return 0;
  47.     }
  48.     }

解题报告(自己归纳的):

 

求next数组的算法自己整理了下  

p 1p2......p(j-1)=s(i-j+1)....s(i-1)

  p1p2...pk-1=s(i-k+1)...s(i-1)=p(j-k+1)....p(j-1)

就是求当pj!=si的时候,求k的最大值(1<k<j)

 对于任意的j都有一个对应的k值,用int next[n+1]数组表示,(next[0]不使用)

next[1]=0

设next[j]=k;即 'p1....p(k-1)'='p(j-k+1)....p(j-1)'

当pk=pj时,即 'p1....p(k-1)pk'='p(j-k+1)....p(j-1)pj'

所以next[j+1]=k+1=next[j]+1;

当pk!=pj时 就要使j=k=next[j],让si与pk比较,如果相等则进行s(i+1)和p(k+1)比较

如果不等,则令j=k'=next[k],让si与pk'比较,以此类推,直到j=0的时候,即整个模式串中都没有与si之前匹配的串,这时候就要令i+1,j+1,进行s(i+1)和p(k+1)比较

next改进为nextval的算法

 si!=pj

当pk=pj时,继续进行p(k+1)与p(j+1)的比较,

如果相等的情况下,即si!=pj所以si!=pk,如果pk==pk',以此类推,直到j回溯到

j=k(n)!=k(n-1)=··k''=k'

此算法就是为了省略模式串中这种情况下j指针的回溯,

所以当pk=pj时,继续进行p(k+1)与p(j+1)的比较,

如果不等则同next算法,

如果相等则把串某一段都是相同元素子串的第一个元素的nextval[]的值赋值给该子串的所有元素


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值