AC自动机模板(hdu2222-Keywords Search)
地址:http://acm.hdu.edu.cn/showproblem.php?pid=2222
题目参考:http://www.notonlysuccess.com/index.php/aho-corasick-automaton/
此题模板:
#include <set> #include <map> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int Max=250010; const int MAX_CHILD=27; int chd[Max][MAX_CHILD],fail[Max],val[Max],ID[128],sz; char s[50]; queue<int>q; int Query(const char *s) { int ret = 0; int cur = 1, tmp;//Trie的根节点为1号节点 for (int i = 0; s[i]; i++) { if (chd[cur][ID[s[i]]]) cur = chd[cur][ID[s[i]]]; else { while (cur != 1 && chd[cur][ID[s[i]]] == 0) cur = fail[cur]; if (chd[cur][ID[s[i]]]) cur = chd[cur][ID[s[i]]]; } tmp = cur; while (tmp != 1 && val[tmp] != -1) { ret += val[tmp]; val[tmp] = -1;//单次匹配 tmp = fail[tmp]; } } return ret; } void Build_AC() { while (!q.empty()) q.pop(); q.push(1); fail[1] = 1; while (!q.empty()) { int cur = q.front(); q.pop(); for (int i = 0; i < MAX_CHILD; i++) if (chd[cur][i]) { if (cur == 1) fail[chd[cur][i]] = 1; else { int tmp = fail[cur]; while (tmp != 1 && chd[tmp][i] == 0) tmp = fail[tmp]; if (chd[tmp][i]) fail[chd[cur][i]] = chd[tmp][i]; else fail[chd[cur][i]] = 1; } q.push(chd[cur][i]); } } } void Insert(const char *s){//建一棵Trie树 int cur=1; for(int i=0;s[i];i++) { if(!chd[cur][ID[s[i]]])chd[cur][ID[s[i]]]=++sz;//sz表示树中一共有多少节点 cur=chd[cur][ID[s[i]]]; } val[cur]++; } char str[1000000]; int main(){ int t; scanf("%d",&t); for(int i=0;i<26;i++) { ID[i+'a']=i; } while(t--){ memset(chd,0,sizeof(chd)); memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); sz=1; int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf(" %s",s); Insert(s); } Build_AC(); scanf(" %s",str); printf("%d\n",Query(str)); } return 0; }