写点自己对KMP的理解,我们有两个字符串A和B,求A中B出现了多少次。
这种问题就可以用KMP来求解。
朴素的匹配最坏情况是O(n^2)的。KMP是个高效的算法,效率是O(n)的。
KMP算法的思想是先将B串与自己匹配,预处理出一个kmp(next)数组,在失配的时候回跳,这样就大大提升了效率。
定义上kmp[1]为-1。暂时就先这样用吧。
1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=1e5+5; 5 char a[maxn],b[maxn]; 6 int kmp[maxn]; 7 int main() 8 { 9 scanf("%s%s",a+1,b+1); 10 int alen=strlen(a+1); 11 int blen=strlen(b+1); 12 for(int i=2,j=0;i<=blen;++i) 13 { 14 while(j&&b[i]!=b[j+1])j=kmp[j]; 15 if(b[i]==b[j+1])j++; 16 kmp[i]=j; 17 } 18 int ans=0; 19 for(int i=1,j=0;i<=alen;++i) 20 { 21 while(j&&a[i]!=b[j+1])j=kmp[j]; 22 if(a[i]==b[j+1])j++; 23 if(j==blen)ans++; 24 } 25 kmp[1]=-1; 26 for(int i=1;i<=blen;++i)printf("%d ",kmp[i]); 27 printf("\n%d\n",ans); 28 return 0; 29 }
给几道例题
洛谷P3375
hdu1686
hdu1711
hdu2087