暴力匹配和KMP算法模板

问题描述:

给出一个文本串S和一个模式串P,判断P是否在S中出现,若出现返回模式串中的位置。


暴力匹配算法思想

假设当前文本串遍历到i,模式串遍历到j:

1.若s[i]==p[j]则文本串和模式串继续匹配

               ++i;

               ++j;

2.若s[i]!=p[j]则文本串和模式串进行回溯后再匹配

              j=0;//模式串回到开头

              i=i-(j-1)=i-j+1;

3.经过若干次1,2过程的匹配知道文本串或模式串遍历完,则判断j?plen i-j:-1;

代码如下:

int ViolentMatch(char *s,char *p){

    int slen=strlen(s);

    int plen=strlen(p);

    int i=0;

    int j=0;

    while(i<slen&&j<plen){

          if(s[i]==p[j]){

                 ++i;

                 ++j;

          }

          else{

                j=0;

                i=i-j+1;

        }

    }

   if(j==plen) return i-j;

   return -1;

}


2.KMP匹配算法思想

(1)整体过程

假设当前文本串遍历到i,模式串遍历到j,

1、若j==-1或s[i]==s[j],则文本串和模式串继续向后匹配

                ++i;

                ++j;

2.若j!=-1且s[i]!=s[j],则文本串不向前回溯即i不变,但模式串j向前回溯到next[j]的位置。

                j=next[j];

3.经过若干次1,2过程的匹配知道文本串或模式串遍历完,则判断j?plen i-j:-1;

int KmpSearch(char *s,char *p){

    int slen=strlen(s);

    int plen=strlen(p);

    int i=0;

    int j=0;

    while(i<slen&&j<plen){

          if(j==-1&&s[i]==p[j]){

                 ++i;

                 ++j;

          }

          else{

               j=next[j];

        }

    }

   if(j==plen) return i-j;

   return -1;

}



(2)next数组计算过程

假设当前存在p0p1...pk-1=pj-kpj-k+1...pj-1

1.若当前存在p[k]==p[j],则next[j+1] =next[j]+1;

2.若当前p[k]!=p[j]则k向前回溯k=next[k];

代码如下:

void GetNext(char *p,int next[]){

   int k=-1;

   int j=0;

   next[i]=0;

  int plen=strlen(p);

  while(j<plen-1){

        if(j==-1||p[k]==p[j]){

              ++k;

              ++j;

              next[j]=k; 

        }

        else{

            k=next[k];

        }

   }

}




(3).优化Next数组的计算过程

主要原因是:

如S:abacd   P:abab 当s[3]和P[3]匹配失败时回溯到s[3]和p[1]匹配此时还是失败的从而影响了匹配效率,此时应该继续向前回溯,优化过程则是在计算next时递归向前回溯。

void GetNext(char *p,int next[]){

int k=-1;

int j=0;

next[i]=0;

int plen=strlen(p);

while(j<plen-1){

        if(j==-1||p[k]==p[j]){

              ++k;

              ++j;

              if(p[k]!=p[j]){

                    next[j]=k; 

              }

              else{

                  next[j]=next[k];//优化过程

             }

        }

        else{

            k=next[k];

        }

}
}


总体来看,KMP算法的时间复杂度O(m+n)空间复杂度O(1)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值