KMP,AC自动机
KMP
http://www.matrix67.com/blog/archives/115
注意这个从1开始字符串,从0开始不好写,不过不优化fail的从0还是好写- -!
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 #define maxn 1000005 7 int n, m, k; 8 int a[maxn],fail[maxn]; 9 char str1[maxn], str2[maxn]; 10 void init(){ 11 int j = 0; 12 for (int i = 2; i <= m; i++){ 13 while (j&&str2[i] != str2[j + 1])j = fail[j]; 14 if (str2[i] == str2[j + 1])j++; 15 fail[i] = j; 16 } 17 } 18 void kmp(){ 19 int j = 0; k = 0; 20 for (int i = 1; i <= n; i++){ 21 while (j&&str1[i] != str2[j + 1])j = fail[j]; 22 if (str1[i] == str2[j + 1])j++; 23 if (j == m){ a[k++] = i - m + 1; j = fail[j]; } 24 } 25 } 26 int main(){ 27 while (~scanf("%s%s", str1+1, str2+1)){ 28 n = strlen(str1 + 1); 29 m = strlen(str2 + 1); 30 init(); 31 kmp(); 32 for (int i = 0; i < k; i++)printf(i==k-1?"%d\n":"%d ", a[i]); 33 } 34 return 0; 35 }
AC自动机
首先要把深度为i之前的fail指针求出来才能求深度为i的fail指针,BFS刚好符合!
最后没看懂的再看看下面的这个回答
某某:我把我的想法说下`是不是`对 ``你最后的那个trie先在要求的是she中h的失败指针,而对``h深度`h-1的失败指针都已经求出来(可以通过归纳证明)所以
对h只要沿着它父亲走失败指针的看失败指针指向的节点是否有一个 儿子和h 相等,而由失败指针的定义。h以上有n个和失败指针到 root之间
匹配,所以 如果找到一个h 说明有n+1个匹配 得证。 希作者看到后联系我- - 看我的理解对不对``还是有更加具体化的思路我没有想到```
这种代码肯定会被各种卡的,知道写,乱改就可以了。。。我都懒得去知道以前写的了
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #include <iostream> 6 using namespace std; 7 #define maxn 1005005 8 #define sz_ 26 9 int n, k, t, sz, cnt; 10 int m[10005]; 11 int q[maxn]; 12 int ch[maxn][sz_]; 13 int fail[maxn]; 14 vector<int>g[10005],val[maxn]; 15 char str1[maxn], str2[105]; 16 void insert(char *str, int v){ 17 int u = 0, len = strlen(str+1); 18 for (int i = 1; i <= len; i++){ 19 int c = str[i] - 'a'; 20 if (!ch[u][c]){ 21 memset(ch[sz], 0, sizeof ch[sz]); 22 val[sz].clear(); 23 ch[u][c] = sz++; 24 } 25 u = ch[u][c]; 26 } 27 val[u].push_back(v); 28 } 29 void bfs(){ 30 int u = 0; 31 int head=0,tail=0; 32 for (int i = 0; i < sz_; i++){ 33 int v = ch[u][i]; 34 if (v){ fail[v] = 0; q[tail++] = v; } 35 } 36 while (head!=tail){ 37 int u = q[head++]; 38 for (int i = 0; i < sz_; i++){ 39 int v = fail[u]; 40 if (!ch[u][i])continue; 41 q[tail++] = ch[u][i]; 42 while (v&&!ch[v][i])v = fail[v]; 43 fail[ch[u][i]] = ch[v][i]; 44 } 45 } 46 } 47 void ac(){ 48 int u = 0; 49 for (int i = 1; i <= n; i++){ 50 int c = str1[i] - 'a'; 51 while (u&&!ch[u][c])u = fail[u]; 52 u=ch[u][c]; 53 int ux = u; 54 while (ux){ 55 for (int j = 0; j < val[ux].size(); j++) 56 g[val[ux][j]].push_back(i - m[val[ux][j]] + 1); 57 ux = fail[ux]; 58 } 59 } 60 } 61 int main(){ 62 while (~scanf("%s", str1 + 1)){ 63 n = strlen(str1 + 1); 64 scanf("%d", &k); 65 cnt = 0; 66 sz = 1; memset(ch[0], 0, sizeof ch[0]); 67 for (int i = 0; i <= 10004; i++)g[i].clear(); 68 for (int i = 1; i <= k; i++){ 69 scanf("%s", str2 + 1); 70 m[i] = strlen(str2 + 1); 71 insert(str2, i); 72 } 73 bfs(); 74 ac(); 75 for (int i = 1; i <= k; i++)cnt+=g[i].size(); 76 printf("%d\n", cnt); 77 for (int i = 1; i <= k; i++) 78 for (int j = 0; j < g[i].size(); j++) 79 printf(j == g[i].size() - 1 ? "%d\n" : "%d ", g[i][j]); 80 for (int i = 0; i <= sz; i++)val[i].clear(); 81 } 82 return 0; 83 }
浙公网安备 33010602011771号