KMP(算法描述)
#include<iostream> using namespace std; const int N=10010,M=100010; int n,m; char p[N],s[M]; int ne[N]; int main () { cin>>n>>p+1>>m>>s+1; //求next:对短数组而言 for(int i=2,j=0;i<=n;i++) { while(j&&p[i]!=p[j+1])j=ne[j];//没匹配上,短的数组就从前边相同的位置开始匹配 if(p[i]==p[j+1])j++; ne[i]=j; } //kmp匹配 for(int i=1,j=0;i<=m;i++) { while(j&&s[i]!=p[j+1])j=ne[j]; if(s[i]==p[j+1])j++; if(j==n)//匹配成功 { cout<<i-n<<' '; j=ne[j]; } } return 0; }
通过减少相同的字符串匹配来进行优化
重点是next数组的求法
j:是小的数组,在进行匹配过程中,比较的是j+1是否相同,当j+1不相同时,将j替换成小数组中前边已经匹配的位置,即next中的对应值。
//当时间复杂度要求不高时可以通过暴力:(一般通过这种方法解决即可)
bool fakekmp() { int s[SMALL],t[MAXN]; int n=strlen(s),m=strlen(t); for(int i=0,p=0;i<m;i++) { if(s[p]==t[i]) p++; else p=0; if(p==n) { return true; } } }