kmp算法(字符串匹配)

参考视频:https://www.bilibili.com/video/BV1jb411V78H?from=search&seid=4313084886343126293

参考博客:https://blog.csdn.net/qq_34181098/article/details/107066929

next数组(模式串):

 1 void buildNext(string& p, int* Next, int n) {
 2     int x,y; // x指针指向前缀,y指向后缀
 3     x = -1;
 4     y = 0;
 5     while(y < n) { // n 为Next数组长度
 6         if(x == -1 || p[x] == p[y]) {
 7             Next[++y] = ++x; // x共用
 8         }
 9         else {
10             x = Next[x]; 
11         }
12     }
13 }

kmp:

 1 int KMP(string t, string p) {
 2     int i = 0; // 主串位置
 3     int j = 0; // 模式串位置
 4     const int len = p.size() + 1;
 5     int next[len] = { -1 };
 6     buildNext(p,next,p.size());
 7 
 8     int tsize = t.size();
 9     int psize = p.size();
10     // while 中的匹配方法是核心,前缀表生成和KMP本体匹配都用这个
11     while(i < tsize && j < psize) {
12         if(j == -1 || t[i] == p[j]) {
13             /*
14                 j = -1 时(next数组-1),直接匹配下一个位置。模式串index和next数组共用
15             */
16             i++;
17             j++;
18         }
19         else {
20             j = next[j]; // 如果匹配不上,则参照next数组表进行位移
21         }
22 
23     }
24     if( j == psize)
25         return i - j;
26     else
27         return -1;
28 }

 

 

模板题:https://www.luogu.com.cn/problem/P3375

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 void build_next(char *s, int *next, int len) {
 6     int x = -1, y = 0;
 7     while(y < len) {
 8         if(x == -1 || s[x] == s[y])
 9             next[++y] = ++x;
10         else
11             x = next[x];
12     }
13 }
14 
15 void kmp(char *mstr, char *pstr) {
16     int i = 0, j = 0;
17     int mlen = strlen(mstr), plen = strlen(pstr) + 1;
18     int next[plen] = {-1};
19     build_next(pstr, next, plen);
20     while(i < mlen) {
21         if(j == -1 || mstr[i] == pstr[j]) {
22             i++;
23             j++;
24         } else {
25             j = next[j];
26         }
27         //cout << "#" << j << "#" << endl;
28         if(j == plen - 1) {
29             cout << i-j+1 << endl;
30             j = next[j];
31         }
32     }
33     for(int i = 1; i < plen;i++) {
34         if(i != 1) cout << " ";
35         cout << next[i];
36     }
37 }
38 
39 int main()
40 {
41     char *s1 = new char[1000000], *s2 = new char[1000000];
42     cin >> s1; cin >> s2;
43     kmp(s1, s2);
44     return 0;
45 }

 

posted @ 2020-09-02 21:57  湖上的程序员  阅读(235)  评论(0编辑  收藏  举报