c++ kmp算法字符匹配_数据结构基础-串模式匹配算法KMP

改进的模式匹配算法(KMP):

改进之处在于,当匹配过程中出现相比较的字符不相等时,不需要回退主串的字符位置指针,而是利用已经得到的“部分匹配”的字符,将模式串向右滑动尽可能远的距离,再进行比较。具体向右滑动多少距离,就得依据next函数值进行计算。依据模式串next函数值整理的表,就叫《部分匹配表》。

滑动距离=已“部分匹配”的字符数-next函数值。

部分匹配表如何产生:

  • 1.第一种方式:

“前缀”:除了最后一个字符外,一个字符串的全部头部组合。

“后缀”:除了第一个字符外,一个字符串的全部尾部组合。

“部分匹配值“:指前缀和后缀的最长共有元素的长度。也就是next函数值。

部分匹配表,就是根据部分匹配值(next函数值)整理得出。

如果模式串为abababb,则部分匹配表如下所示:

6dbec1bedb55b77d217605c7c9175f80.png

部分匹配表

我们定义下标0为字符串的开始,规定next[0]=-1;

j=1时,前面字符串a,前缀和后缀都为空集,共有元素最长长度为0;

j=2时,前面字符串ab,前缀为【a】,后缀为【b】,没有共有元素,共有元素最长长度为0;

j=3时,前面字符串aba,前缀为【a】【ab】,后缀为【a】【ba】,共有元素最长长度为1;

j=4时,前面字符串abab,前缀为【a】【ab】【aba】,后缀为【b】【ab】【bab】,共有元素最长长度为2;

j=5时,前面字符串ababa,前缀为【a】【ab】【aba】【abab】,后缀为【a】【ba】【aba】【baba】,共有元素最长长度为3;

j=6时,前面字符串ababab,前缀为【a】【ab】【aba】【abab】【ababa】,后缀为【b】【ab】【bab】【abab】【babab】,共有元素最长长度为4;

  • 2.第二种方式

next函数定义如下:

63b62de371bf4313b00d18978c325649.png

next函数

如果模式串为abababb,根据next函数:

当j=0时,next[0]=-1。

当j=1时,因0

当j=2时,0

当j=3时,0

当j=4时,0

当j=5时,0

依次计算,就可以得到如图部分匹配表中的结果。

next函数推导过程如下:

我们定义串中的位置指针分别为i(主串指针)和j(模式串指针),第一个位置以下标0开始,如下图所示:

e04f7b94d340e2f8d549bd56cdbe790f.png

根据KMP基本思想,当匹配到C和B不相等时,指针需要移动一定的距离,通过看上图我们发现,j需要移动到第二个位置,即C处,如下图所示的位置:

cccbf6cd8c06f0ca4d2fd4e6f94ce83b.png

我们设匹配失败时,j要移动的下一个位置为k,此时k移动的位置只能在0到k之间,即0

1b93b01b0a0f8bd5b11d376bd02185ae.png

定义主串字符组为T,模式串字符组为P。

如上图所示,此时我们发现0

整体总结如下:

当T[i] != P[j]时

由T[i-j ~ i-1] = P[0~j-1]

由P[0 ~ k-1] == P[j-k ~ j-1]

必然:T[i-k ~ i-1] == P[0 ~ k-1]

next函数值算法脚本

db20e5db853149885922951c7b58f67f.png

next函数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值