代码改变世界

字符串匹配之KMP算法

2014-09-04 15:34  微尘_无名  阅读(143)  评论(0编辑  收藏  举报

KMP算法使用前缀函数来模拟有限自动机的后缀函数,前缀函数通过计算模式与其自身的偏移匹配的信息,本身的证明很复杂,关键在于弄懂其核心思想,下面就不赘述了,仅仅贴出代码:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 int const  MAX_N = 1000;
 6 int pi[MAX_N];
 7 
 8 void COMPUTE_PREFIX_FUNCTION(string& P)
 9 {
10     int m = P.length() - 1;
11     pi[1] = 0;
12     int k = 0;
13     for(int q = 2; q <= m; q++)
14     {
15         while(k > 0 && P[k + 1] != P[q])
16             k = pi[k];
17         if(P[k + 1] == P[q])
18             k++;
19         pi[q] = k;
20     }
21 }
22 
23 void KMP_MATCHER(string& T, string& P)
24 {
25     int n = T.length() - 1;
26     int m = P.length() - 1;
27     int q = 0;
28     for(int i = 1; i <= n; i++)
29     {
30         while(q > 0 && P[q + 1] != T[i])
31             q = pi[q];
32         if(P[q + 1] == T[i])
33             q++;
34         if(q == m)
35         {
36             cout<<"Pattern occurs with shift "<<i - m<<endl;
37             q = pi[q];
38         }
39     }
40 }
41 
42 int main()
43 {
44     //为了和书上保持一致,这里在字符串前面添加了一个空格,使得真正有效的字符串的起始下标为1
45     string T = " abababacaba";
46     string P = " ababaca";
47     COMPUTE_PREFIX_FUNCTION(P);
48     KMP_MATCHER(T,P);
49     return 0;
50 }
View Code