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