1. 程式人生 > >UvalLive4670(AC自動機模板)

UvalLive4670(AC自動機模板)

ast ++ 別人 轉移 pan pre algo continue i++

放上劉汝佳的模板:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <string>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <map>
  7 using namespace std;
  8 
  9 const int maxnod = 150 * 70 + 100;
 10 
 11 int n;
 12 char str[155][75], T[1000005];
13 map<string, int> mp; 14 15 struct AC_Automata { 16 int ch[maxnod][26];//Trie樹轉移 17 int cnt[155];//每個子串出現了幾次 18 int val[maxnod];//某節點是否為子串結尾以及是哪個串的結尾 19 int f[maxnod];//失配,轉移到別的樹枝繼續找 20 int last[maxnod];//找到了後綴相同的其他可行子串 21 int sz; 22 23 void init() {
24 sz = 1; 25 mp.clear();//與ac自動機無關 26 memset(ch[0], 0, sizeof ch[0]); 27 memset(cnt, 0, sizeof cnt); 28 } 29 30 int idx(char c) { return c - a; } 31 32 void insert(char* s, int v) {//Trie樹的插入 33 int u = 0, n =strlen(s); 34 for
(int i = 0; i < n; ++i) { 35 int c = idx(s[i]); 36 if (!ch[u][c]) { 37 memset(ch[sz], 0, sizeof ch[sz]); 38 val[sz] = 0; 39 ch[u][c] = sz++; 40 } 41 u = ch[u][c]; 42 } 43 val[u] = v; 44 } 45 46 void getfail() { 47 queue<int> Q; 48 f[0] = 0; 49 for (int i = 0; i < 26; i++) { 50 int u = ch[0][i]; 51 if (u) { 52 f[u] = last[u] = 0; 53 Q.push(u); 54 } 55 } 56 while (!Q.empty()) { 57 int r = Q.front(); Q.pop(); 58 for (int c = 0; c < 26; c++) { 59 int u = ch[r][c]; 60 if (!u) continue; 61 Q.push(u); 62 int v = f[r]; 63 while (v && !ch[v][c]) v = f[v];//當前這個不行看看別人行不行 64 f[u] = ch[v][c]; 65 last[u] = val[f[u]] ? f[u] : last[f[u]]; 66 } 67 } 68 } 69 70 void Success(int j) { 71 if (j) { 72 cnt[val[j]]++; 73 Success(last[j]); 74 } 75 } 76 77 void find(char* T) { 78 int n = strlen(T); 79 for (int i = 0, j = 0; i < n; ++i) { 80 int c = idx(T[i]); 81 while (j && !ch[j][c]) j = f[j]; 82 j = ch[j][c]; 83 if (val[j]) Success(j); 84 else if (last[j]) Success(last[j]); 85 } 86 } 87 }ac; 88 89 int main() { 90 while (~scanf("%d", &n) && n) { 91 ac.init(); 92 for (int i = 1; i <= n; i++) { 93 scanf("%s", str[i]); 94 ac.insert(str[i], i); 95 mp[str[i]] = i; 96 } 97 ac.getfail(); 98 scanf("%s", T); 99 ac.find(T); 100 101 int ans = -1; 102 for (int i = 1; i <= n; i++) { 103 ans = max(ans, ac.cnt[i]); 104 } 105 printf("%d\n", ans); 106 for (int i = 1; i <= n; i++) { 107 if (ac.cnt[mp[str[i]]] == ans) puts(str[i]); 108 } 109 } 110 return 0; 111 }

UvalLive4670(AC自動機模板)