您的位置:首页 > 其它

HDU 2222 Keywords Search [AC自动机]

2017-07-14 21:16 471 查看
AC自动机模板题。

学习建Trie树并在其上构建fail(Trie+KMP),这就是AC(自动机),那么有什么关键点吗?

那就是字符串题是我唯一会全程用指针构造的题,即使是数据结构,使用数组都会有指针比不上的优势。

什么指针写出来清晰?

等你天天艹树,会发现其实都差不多的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define rez(i,x,y) for(int i=x;i>=y;i--)
#define res(i,x,y) for(int i=x;i<=y;i++)
#define INF 0x3f3f3f3f
#define ll long long
#define clr(x)  memset((x),0,sizeof(x))
using namespace std;
const int N = 500010;
int t,n,head,tail;
char str[1000010],key[55];
struct node{
node *fail,*nxt[26];
int cnt;
node(){
fail=NULL,cnt=0;
for(int i=0;i<26;i++)nxt[i]=NULL;
}
}*tree
,*root;
void insert(char *s){
int tmp,len=strlen(s);
node *p=root;
for(int i=0;i<len;i++){
tmp=s[i]-'a';
if(p->nxt[tmp]==NULL)
p->nxt[tmp]=new node();
p=p->nxt[tmp];
}
p->cnt++;
}
int find(){
int tmp,len=strlen(str),ans=0;
node *p=root;
for(int i=0;i<len;i++){
tmp=str[i]-'a';
while(p->nxt[tmp]==NULL&&p!=root)p=p->fail;
p=p->nxt[tmp];
if(p==NULL)p=root;
node *q=p;
while(q!=root&&q->cnt!=-1)
ans+=q->cnt,q->cnt=-1,q=q->fail;
}
return ans;
}
void build_AC(){
tree[tail++]=root;
while(head!=tail){
node *p=tree[head++],*tmp=NULL;
for(int i=0;i<26;i++){
if(p->nxt[i]!=NULL){
if(p==root)p->nxt[i]->fail=root;
else{
tmp=p->fail;
while(tmp!=NULL){
if(tmp->nxt[i]!=NULL){p->nxt[i]->fail=tmp->nxt[i];break;}
tmp=tmp->fail;
}
if(tmp==NULL)p->nxt[i]->fail=root;
}
tree[tail++]=p->nxt[i];
}
}
}
}
int main(){
scanf("%d",&t);
while(t--){
head=tail=0;
root=new node();
scanf("%d",&n);getchar();
for(int i=1;i<=n;i++)
gets(key),insert(key);
build_AC();
scanf("%s",str);
cout<<find()<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: