KMP理解

认识kmp前 先了解下BF(暴力穷举)

查找子串在主串中首次出现的位置,若未出现输出0:

#include <bits/stdc++.h>
using namespace std;
int main(){
	char a[1000],b[1000];
	gets(a);	            //主串
	gets(b);
	int i=0,j=0;
	while(a[i]!='\0' && b[j]!='\0'){
		if(a[i]==b[j]){
			j++;
			i++;
		}
		else{
			i=i-j+1;	    //i=1 2 3 ....
			j=0;
		}
	}
	if(b[j]=='\0')
		cout<<i-j+1;
	else
		cout<<"0";
	return 0;
		
}

然而,这种方法效率极低,需要像乌龟一样慢慢往后爬。就此引出KMP算法。


了解kmp前先补充的知识:
前缀 后缀 前后缀公共最大长

了解之后,引入next数组,将从开头到此位置的子串的部分串(又或者叫子串的子串)的前后缀公共最大长存入。

 new数组是next数组的数值-1

关于next数组的值,是需要自己求出来的。具体的求法后边再说。


现将A串(主串)和B串匹配

 到第6位的时候(下标为5)匹配失败,查找前边匹配成功的长度为5的子串的最大公共长。

然后主串依旧从第6位开始匹配,子串从第(最大公共长+1)的位置开始匹配。

譬如第一轮匹配失败后,abaab的最大公共长是2,最大公共长+1的位置就是3,就从a[5]是否等于b[2]往后开始判断,进行新一轮的匹配,依次循环。


现在要解答上边的疑问,如何求next数组(或者new数组):

为了说明通解,不从第二位开始,就假设next[0]~next[9]均已经求出来,则要判断b[10]b[10]前的最长字符串“abaabbabaa”最大前缀的后一位是否相等。

而现在如何找“abaabbabaa”最大前缀的后一位?答案即下标为next[9]的索引值。(next[9]对应了公共最大长的值,也表示着最大前缀后一位的索引)

若相等,则next[10]=next[9]+1。若不相等,譬如最后b[10]=a,此时b[10]前的最长字符串“abaabbabaa”最大前缀是(或者叫最大后缀,二者相等)“abaa”,即问题转换成了求“abaa”后加了“a”,也就是新串“abaaa”的最大公共长,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值