AC自动机
Posted gggyt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。
AC自动机是著名的多模匹配算法之一。常见的例子就是给出n个单词,再给你包含m个字符的文章,问你有多少个单词在文章中出现过。
其实AC自动机是以字典树和KMP的基础上实现的。
首先要构造一个Tire,然后再在上面构造失配然后再匹配。
但是我现在还是不怎么懂失配是怎么弄的,先留个坑,后面来填。
模板:
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring>` #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 10000+5; const ll maxm = 1e7; const ll mod = 1e9 + 7; const int INF = 0x3f3f3f; const ll inf = 1e15 + 5; const db eps = 1e-9; const int kind=26; struct node{ node *fail; node *next[kind]; int coun; void nodee() { fail=NULL; coun=0; for (int i=0; i<kind; i++) next[i]=NULL; } }*root; char str[1000000+100]; void updata() { node *p=root; int len=strlen(str); for (int i=0; i<len; i++) { int pos=str[i]-‘a‘; if (p->next[pos]==NULL) { p->next[pos]=new node; p->next[pos]->nodee(); p=p->next[pos]; } else p=p->next[pos]; } p->coun++; // cout<<p->coun<<endl; } void getfail() { node *p=root, *son, *tmp; queue<struct node*>que; que.push(p); while(!que.empty()) { tmp=que.front(); que.pop(); for (int i=0; i<26; i++) { son=tmp->next[i]; if (son!=NULL) { if (tmp==root) { son->fail=root; } else { p=tmp->fail; while(p) { if (p->next[i]) { son->fail=p->next[i]; break; } p=p->fail; } if (!p) son->fail=root; } que.push(son); } } } } void query() { int len=strlen(str); node *p, *tmp; p=root; int cnt=0; for (int i=0; i<len; i++) { int pos=str[i]-‘a‘; while(!p->next[pos]&& p!=root) p=p->fail; p=p->next[pos]; if (!p) p=root; tmp=p; while(tmp!=root) { if (tmp->coun>=0) { cnt+=tmp->coun; tmp->coun=-1; } else break; tmp=tmp->fail; } //cout<<cnt<<endl; } printf("%d\n", cnt); } void solve() { root=new node; root->nodee(); root->fail=NULL; int n; scanf("%d", &n); getchar(); for (int i=0; i<n; i++) { gets(str); updata(); } getfail(); gets(str); query(); } int main() { int t = 1; // freopen("in.txt", "r", stdin); scanf("%d", &t); while(t--) solve(); return 0; }
以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章
HDU4057 Rescue the Rabbit(AC自动机+状压DP)
Codeforces 86C Genetic engineering(AC自动机+DP)
POJ1699 Best Sequence(AC自动机+状压DP)