模板——AC自动机
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxnode = 10000; 9 const int _size = 26; 10 11 struct ACauto { 12 int ch[maxnode][_size]; 13 int val[maxnode]; 14 int f[maxnode]; 15 int last_[maxnode]; 16 int sz; 17 ACauto() { 18 sz = 1; 19 memset(ch[0], 0, sizeof (ch[0])); 20 } 21 int idx(int c) {return c - 'a';} 22 23 void insert(char *s, int v) { //插入字符串s和权值v 24 int u = 0, n = strlen(s); 25 for(int i = 0; i < n; i++) { 26 int c = idx(s[i]); 27 if(!ch[u][c]) { 28 memset(ch[sz], 0, sizeof (ch[sz])); 29 val[sz] = 0; 30 ch[u][c] = sz++; 31 } 32 u = ch[u][c]; 33 } 34 val[u] = v; 35 } 36 void clear() { 37 sz = 1; 38 memset(val, 0 , sizeof val); 39 memset(ch[0], 0, sizeof (ch[0])); 40 memset(f, 0, sizeof f); 41 memset(last_, 0, sizeof last_); 42 } 43 //计算失配函数 44 void getfail() { 45 queue<int> q; 46 for(int c = 0; c < _size; c++) { 47 int u = ch[0][c]; 48 if(u) { 49 q.push(u); 50 f[u] = 0; 51 last_[u] = 0; 52 } 53 } 54 while(!q.empty()) { 55 int r = q.front(); q.pop(); 56 for(int c = 0; c < _size; c++) { 57 int u = ch[r][c]; 58 if(!u) { 59 ch[r][c] = ch[f[r]][c]; 60 continue; 61 } 62 q.push(u); 63 int v = f[r]; 64 while(v && !ch[v][c]) v = f[v]; 65 f[u] = ch[v][c]; 66 last_[u] = val[f[u]] ? f[u] : last_[f[u]]; 67 } 68 } 69 } 70 //打印以j结尾的所有模板串序号 71 void print(int i,int j) { 72 if(j) { 73 printf("%d : %d\n", i, val[j]); 74 print(i,last_[j]); 75 } 76 } 77 //在文本串中找模板 78 void find(char* T) { 79 int n = strlen(T); 80 int j = 0; 81 for(int i = 0; i < n; i++) { 82 int c = idx(T[i]); 83 j = ch[j][c]; 84 if(val[j]) print(i, j); 85 else if(last_[j]) print(i, last_[j]); 86 } 87 } 88 };