KMP字符串匹配(1)

近日看到一面试题写一个函数从字符串s中查找出子串t,并将t从s中删除。

这是考查KMP匹配算法,以前读书时学KMP总是一知半解,考完试基本都还给老师了,

唯一的印象就是KMP实现了匹配字符串指针不回溯,极大的提高了效率,

最近代码写的少拿此题练练手。

考虑当第k个字符失配的时候,sm+k+1tk+1时,有如下关系

sm+1sm+2…sm+k = t1t2…tk

下一次再比较时,指针不回溯,应该比较sm+k+1和t的哪个字符呢?

假设应该和ti比较,那么有如下关系

t1t2…ti-1 = sm+k-i+2sm+k-i+3…sm+k (i-1<k)

t1t2…ti-1 = tk-i+2tk-i+3…tk (i-1<k)这是字符串t自身的匹配关系,

当然这样的i可能不止一个,next[i]就是所有这样i里面的最大值,

i越大也意味着满足t1t2…ti-1 = tk-i+2tk-i+3…tk关系的k-i+2越小,

因此下一个需要比较的就是满足上述条件i的最大值,失配后t往右移动的距离最小,

字符串t第i个字符失配后sm+k+1应该和t的next[i]个字符继续比较。

举个具体例子s=“ababababababc“, t=“abababc“当s[6]=a与t[6]=c失配时,

s[6]应该和t[4]=a继续比较,再失配和t[2]=a比较,而不能先和t[2]=a比较,

这样如果原始字符串s=“ababababc“结果就不对了。

有了上述推理,不难写出匹配代码:

i,j分别指向s,t中某个字符,一直匹配,直到某字符失配后,j=next[j]继续比较,

如果next[j]=-1,表示第一个字符就不匹配,此时++i, 比较s的下一个字符,

tlen-j是字符串中待比较字符个数,循环退出条件是s中剩余字符小于t中待比较字符数。

while(i<=slen-tlen+j){

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

                  ++i;

                  ++j;

                  //find match string, erase it

                  if ( j == tlen){ 

                          strcpy(s+i-tlen, s+i);

                          slen -= tlen;

                          i -= tlen;

                          j = 0;

                  }

         }

         else{

                 if ( (j = next[j]) == -1 ){

                         ++i;

                         j = 0;

                       }

         }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值