KMP


 1 const int maxn = 1e5 + 5;
 2 int n, m;  // n 主串长度, m模式串长度
 3 string a, b;  // a 主串, b 模式串, 下标从零开始
 4 int _next[maxn], nextval[maxn];
 5 void get_next() {
 6     int i = 0, j;
 7     j = _next[0] = -1;
 8     while (i < m)
 9     {
10         if (-1 == j || b[i] == b[j])
11             _next[++i] = ++j;
12         else
13             j = _next[j];
14     }
15 }
16 
17 void get_nextval() {
18     int i = 0, j;
19     j = nextval[0] = -1;
20     while (i < m) {
21         if (-1 == j || b[i] == b[j]) {
22             ++i, ++j;
23             nextval[i] = (b[i] != b[j]) ? j : nextval[j];
24         }
25         else {
26             j = nextval[j];
27         }
28     }
29 }
30 
31 int kmp_index(int pos) {
32     // 求模式串在主串 pos位置 字符之后的位置
33     int i = pos, j = 0;
34     while (i < n && j < m) {
35         if (-1 == j || a[i] == b[j]) {
36             ++i, ++j;
37         }
38         else {
39             j = nextval[j];
40         }
41     }
42     if (j >= m) return i - m;
43     else return -1;
44 }
45 
46 int kmp_count(int pos) {
47     // 求模式串在主串中出现了几次
48     int i = pos, j = 0;
49     int ans = 0;
50     while (i < n) {
51         if (-1 == j || a[i] == b[j]) {
52             ++i, ++j;
53             if (j >= m) {
54                 ++ans;
55                 //q.push(i);
56                 j = nextval[j];
57             }
58         }
59         else
60             j = nextval[j];
61     }
62     return ans;
63 }
64 
65 int main()
66 {
67     cin >> a >> b;
68     n = a.size(); m = b.size();
69     get_next();
70     get_nextval();
71     int Index = kmp_index(0);
72     int Count = kmp_count(0);
73     cout << Index << ' ' << Count << endl;
74     return 0;
75 }

 

 

 

posted @ 2020-02-05 14:18  Kiana-  阅读(100)  评论(0)    收藏  举报