KMP算法通透讲解

kmp思想:
如果si 与 pj相等,就i++,j++
si 与 pj不相等,j回退到next[j]
例: s: abaabaabeca p:abaabe 比到index[5] char e时发现 e和a不相等,只需要回退到next[5]的位置。
如何求next[] 动态规划的思想,假设已经知道了回退的位置为k。 前缀为 p0 pk-1 后缀为 p(j-k) p(j-1) 都为len k。
并且根据dp思想, 如果pk = pj 前缀为 p0 pk 后缀为 p(j-k) p(j) 都为 len k+1。复用上一次的结果
如果pk != pj k=next[k] (相当于dp查表) 循环的找满足条件的case [!!!这一步稍难,为什么回退到]

next数组:next[j] = i 的意义是 小于j的index中跟j有公共前缀的最大的i,这里的公共前缀是要求长度为i

void GetNext(string& pat, int next[]){
	int n = pat.size();
	next[0] = -1; // -1表示没有小于j的index跟j有公共前缀,只对0有效,因为其他的j都可以至少跟0有公共前缀--空字符串)
	int k = -1, j = 0;
	while(j < n - 1){
		if(k == -1 || pat[j] == pat[k])
			next[++j] = ++k;
		else
			k = next[k];
	}
}

数学归纳法证明

  • a. 第一次进入循环,k == -1,next[1] = 0,这是对的,
    因为比1小的数只有0,1和0 有公共前缀长度为0,此时j=1,k=0;
  • b. a中保证了第一次循环开始的时候,(j,k) 组成了一个合法的对。
    第二次以及以后,(j,k)合法而且pat[j] == pat[k]情况下(j+1,k+1)合法。
    所以判断条件为pat[j] == pat[k]是否成立,不成立通过 k = next[k],找之前的k对于pat[j] == pat[k]是否成立。
    如果一直找到k==0时仍然不成立,那么k=next[k]使得k变成-1. (j+1, k+1)即(j+1, 0)是合法的。
    所以我们要么找到一个k(k>=0)使得(j+1, k+1)合法,要么找不到一个大于0的k,k此时为-1,(j+1, k+1)仍然合法。
- https://zhuanlan.zhihu.com/p/201631290
 * https://blog.csdn.net/v_july_v/article/details/7041827
 * https://my.oschina.net/duanvincent/blog/3232256
 * https://zhuanlan.zhihu.com/p/76348091
 * https://www.bilibili.com/video/BV1gr4y1B7dF
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值