kmp与扩展kmp的模版

kmp的next数组模版(以0开头的):

void SetPrefix(const char *Pattern, int prefix[])

{

     int len=strlen(Pattern);//模式字符串长度。

     prefix[0]=0;

     for(int i=1; i<len; i++)

     {

         int k=prefix[i-1];

         //不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推

         while( Pattern[i] != Pattern[k]  &&  k!=0 )

             k=prefix[k-1];     //继续递归

         if( Pattern[i] == Pattern[k])//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++

              prefix[i]=k+1;

         else

              prefix[i]=0;       //如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0

     }

}

kmp的匹配模版:

int kmp(const char T[],const char P[],int next[])
 {
     int n,m;
     int i,q;
     n = strlen(T);
     m = strlen(P);
     makeNext(P,next);
     for (i = 0,q = 0; i < n; ++i)
     {
         while(q > 0 && P[q] != T[i])
             q = next[q-1];
         if (P[q] == T[i])
         {
             q++;
         }
         if (q == m)
         {
             printf("Pattern occurs with shift:%d\n",(i-m+1));
         }
     }    
 }

扩展kmp的next数组模版:

void getNext(char* T,int* next){  
    int len=strlen(T), a=0;  
    next[0]=len;  
    while(a<len-1 && T[a]==T[a+1]) ++a;  
    next[1]=a;  
    a=1;  
    for(int k=2; k<len; ++k){  
        int p=a+next[a]-1, L=next[k-a];  
        if(k+L-1>=p){  
            int j=max(p-k+1,0);  
            while(k+j<len && T[k+j]==T[j])++j;  
            next[k]=j;  
            a=k;  
        }  
        else  
            next[k]=L;  
   }  
}  


扩展kmp的extend数组模版:

void EKMP(char* S,char* T,int* next, int* extend){    
    getNext(T,next);    
    int slen=strlen(S), tlen=strlen(T), a=0;    
    int minlen=min(slen,tlen);    
    while(a<minlen && S[a]==T[a])++a;    
    extend[0] = a;    
    a=0;    
    for(int k=1; k<slen; ++k){    
        int p=a+extend[a]-1, L=next[k-a];    
        if(k-1+L >= p){    
            int j=max(p-k+1,0);    
            while(k+j<slen && j<tlen && S[k+j]==T[j]) ++j;    
            extend[k] = j;    
            a=k;    
        }    
        else    
            extend[k] = L;    
    }    
}     
  




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值