标签:include 模式 pop keyword 自动机 names ons pre nbsp
https://vjudge.net/problem/HDU-2222
题意:
给出若干个模式串,然后给出文本串,问这些模式串在文本串中出现了几次。
思路:
妥妥的ac自动机,没有什么好说的,直接上模板,不过要注意maxn的大小是跟文本串的长度一样的。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 using namespace std; 5 6 const int maxn = 1000005; 7 8 struct ac_auto 9 { 10 int chd[maxn][26],v[maxn],f[maxn],last[maxn],sz,ans; 11 12 void init() 13 { 14 sz = 1; 15 ans = 0; 16 17 memset(chd[0],0,sizeof(chd[0])); 18 memset(f,0,sizeof(f)); 19 memset(v,0,sizeof(v)); 20 } 21 22 void insert(char *p) 23 { 24 int cur = 0; 25 for (;*p;p++) 26 { 27 if (!chd[cur][*p-‘a‘]) 28 { 29 memset(chd[sz],0,sizeof(chd[sz])); 30 chd[cur][*p-‘a‘] = sz++; 31 } 32 cur = chd[cur][*p-‘a‘]; 33 } 34 v[cur]++; 35 } 36 37 bool query(char *p) 38 { 39 int cur = 0; 40 41 for (;*p;p++) 42 { 43 if (!chd[cur][*p-‘a‘]) break; 44 cur = chd[cur][*p-‘a‘]; 45 } 46 47 return v[cur] && (!(*p)); 48 } 49 50 void getfail() 51 { 52 queue<int> q; 53 54 f[0] = 0; 55 56 for (int c = 0;c < 26;c++) 57 { 58 int u = chd[0][c]; 59 60 if (u) 61 { 62 f[u] = 0;q.push(u); 63 last[u] = 0; 64 } 65 } 66 67 while (!q.empty()) 68 { 69 int r = q.front();q.pop(); 70 71 for (int c = 0;c < 26;c++) 72 { 73 int u = chd[r][c]; 74 75 if (!u) 76 { 77 chd[r][c] = chd[f[r]][c]; 78 continue; 79 } 80 81 q.push(u); 82 83 int vv = f[r]; 84 85 while (vv&&!chd[vv][c]) vv = f[vv]; 86 f[u] = chd[vv][c]; 87 last[u] = v[f[u]] ? f[u] : last[f[u]]; 88 } 89 } 90 } 91 92 void solve(int j) 93 { 94 if (!j) return; 95 if (v[j]) 96 { 97 ans += v[j]; 98 v[j] = 0; 99 } 100 101 solve(last[j]); 102 } 103 104 void find(char *t) 105 { 106 int n = strlen(t),j = 0; 107 getfail(); 108 109 for (int i = 0;i < n;i++) 110 { 111 j = chd[j][t[i]-‘a‘]; 112 113 if (v[j]) solve(j); 114 else if (last[j]) solve(last[j]); 115 } 116 } 117 }ac; 118 119 char tt[1000005]; 120 121 int main() 122 { 123 int t; 124 125 scanf("%d",&t); 126 127 while (t--) 128 { 129 ac.init(); 130 131 int n; 132 133 scanf("%d",&n); 134 135 for (int i = 0;i < n;i++) 136 { 137 char tmp[60]; 138 139 scanf("%s",tmp); 140 141 ac.insert(tmp); 142 } 143 144 scanf("%s",tt); 145 146 ac.find(tt); 147 148 printf("%d\n",ac.ans); 149 } 150 151 return 0; 152 }
标签:include 模式 pop keyword 自动机 names ons pre nbsp
原文地址:http://www.cnblogs.com/kickit/p/7252466.html