KMP算法为字符串匹配时用,能够实现O(n)的复杂度完成匹配。
我们考虑一般的暴力匹配,其复杂度为O(nm)。
然而它的可以优化的。
任何一种优化都是能够充分运用已拥有的信息,KMP算法亦然。
我们设模板串a,待匹配串b。
它通过一个关于字符串b的next数组,告诉你当匹配到某位失效的时候,你可以从b串之前的某一位继续匹配当前a串的某位,而不必从b串第一位开始匹配。
具体的求法,可以用b串来匹配b串来求得。
在这里的next数组,个人理解为当第i位可以追溯到第next[i]位,即若在第i+1位匹配失败时,我们可以回到next[i]位继续匹配。在这里,我们令s[i]为b串的前i位字符串,则s[next[i]-1]是s[i]的最大前后缀(就是s[i]的后缀的最长前缀,如aba是abaaaabbaba的最大前后缀,当最后的a的后一位匹配失败时,我们就回到第3+1位继续匹配)

1 #include<iostream>
2 #include<string>
3 using namespace std;
4 string qwq,qaq;
5 int next[1000008],m,n;
6 void makenext(){
7 next[0]=0;
8 int k=0;
9 for (int i=1;i<n;i++){
10 while ((k>0)&&(qaq[k]!=qaq[i])) k=next[k-1];
11 if (qaq[k]==qaq[i]) k++;
12 next[i]=k;
13 }
14 }
15 void kmp(){
16 makenext();
17 int q=0;
18 for (int i=0;i<m;i++){
19 while ((qwq[i]!=qaq[q])&&(q>0)) q=next[q-1]; //匹配失败,回到next[q-1]位
20 if (qwq[i]==qaq[q]) q++;
21 if (q==n) cout<<(i-q+2)<<endl;
22 }
23 }
24 int main(){
25 cin>>qwq; //模板串
26 cin>>qaq; //带匹配串
27 m=qwq.size();
28 n=qaq.size();
29 kmp();
30 return 0;
31 }
要形象理解的可参考另一篇:http://www.cnblogs.com/c-cloud/p/3224788.html
来源:https://www.cnblogs.com/Lanly/p/7401306.html
