KMP算法
什么是KMP算法?
先问个问题:给定字符串a和b,满足b一定是a的子串,问第一次b和a重叠的b[1]所对应的a的序号。
举个例子:a:ababcedabced,b:abced
那么答案显然是3,即a[3]开始第一次与b相同。
那么很容易想到的暴力算法为O(N*M),对吧?
显然容易TLE……
这里我们介绍一种简单的字符串匹配算法:KMP。
举个例子:a:ababc,b:abc;
i=1,j=1时,a[i]=b[j],继续,i++,j++,a[i]=b[j],继续,i++,但是这是a[i]!=b[j+1],j不能++,
怎么办?
我们可以把b数组整体迁移,(注意对应关系,如下)
a:ababc
b: abc
这是j=1,i=3,a[i]=b[j],继续……
那么我们不难得到主函数:
j=0; for(int =1;i<=n;i++) { while(j>0&&b[j+1]!=a[i]) j=p[j]; if(b[j+1]=a[i]) j++; if(j==m) ans=i-m; }
那么p数组怎么求,即怎么把b数组移位?
跟主函数很像:
p[1]=0; j=0; for(int i=2;i<=m;i++) { while(j>0&&b[j+1]!=b[i])j=p[j]; if(b[j+1]==b[i]) j++; p[i]=j; }
你学会了吗?