KMP笔记

首先是紧张刺激的预处理环节(自我匹配)
目的是处理出ne数组
ne[j]代表的是:从头开始数直到*j的匹配最长的位置
(例子:S1当前位为bac,S2是bal,我们要找到上一个ba,看看是不是bal)
例如:
原串:abababcac
ne数组001234010

基本思路是:在前缀相同的情况下,不断向下匹配。
分三种情况:
第一:前缀不同:往前退一个前缀进行匹配
第二:前缀相同但下一位不匹配:按ne往前退,直到为0 或者下一位匹配。
第三:前缀相同且下一位匹配:向后匹配

for (int i = 2, j = 0; i <= lc; i ++ ){//从第二位开始自我匹配,第一位只能退回到0 
	//n-1次循环,找到第2~n位的ne,这里用j来赋值
	//情况二:前缀相同但下一位不匹配 
    while (j && c[i] != c[j + 1]) {
		j = ne[j];//往前退一个前缀进行匹配
	}
	//接下来是情况三,或者是退回到0 
    if (c[i] == c[j + 1])  {//如果是情况三 
		j++;//往下一位匹配 
	}
    ne[i] = j;
}
//接着基本是复制粘贴
for (int i = 1, j = 0; i <= ls; i ++ ){
	//找到短串最靠后且下一位匹配的位置,如果一直退到0就不用找了 
    while (j && s[i] != c[j + 1]) {
    	j = ne[j];
	}
	//要确保短串1~j与长串1~i时匹配的 
    if (s[i] == c[j + 1]) {
    	j++;
	}
	//后面就根据题目来写了, 
    if (j == lc){
        ans ++;
        j = ne[j];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值