您的位置:首页 > 其它

hdu 2222(AC自动机模板)

2010-05-13 14:06 573 查看
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int size=26;
char key[55],dir[1000005];
class ac_auto
{
public:
ac_auto *fail;
ac_auto *next[size];
int cnt;
ac_auto()
{
fail=NULL;
cnt=0;
memset(next,NULL,sizeof(next));
};
void Insert(ac_auto *root,char *str)    //构造trie树
{
int i=0,index;
ac_auto *tmp=root;
while(str[i])
{
index=str[i]-'a';
if(tmp->next[index]==NULL)
tmp->next[index]=new ac_auto();
tmp=tmp->next[index];
i++;
}
tmp->cnt++; //单词结尾,计数加1
};
void build(ac_auto *root)   //构造自动机
{
queue<ac_auto*> que;
int i;
ac_auto *tmp,*p;
root->fail=NULL;
que.push(root);
while(!que.empty())
{
tmp=que.front();
que.pop();
p=NULL;
for(i=0;i<size;++i)
{
if(tmp->next[i]!=NULL)
{
if(tmp==root)   tmp->next[i]->fail=root;
else
{
p=tmp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
tmp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) tmp->next[i]->fail=root;
}
que.push(tmp->next[i]);
}
}
}
};
int query(char *str,ac_auto *root)  //查询,返回之前构造的树中有多少字串出现在str中
{
int i=0,count=0,index,len=strlen(str);
ac_auto *tmp=root,*t;
while(str[i])
{
index=str[i]-'a';
while(tmp->next[index]==NULL && tmp!=root) tmp=tmp->fail;
tmp=tmp->next[index];
if(tmp==NULL)   tmp=root;
t=tmp;
while(t!=root)
{
cnt+=t->cnt;
t->cnt=0;
t=t->fail;
}
i++;
}
return cnt;
};
};
int main()
{
int cas,n;
scanf("%d",&cas);
while(cas--)
{
ac_auto *root = new ac_auto();
scanf("%d",&n);
while(n--)
{
scanf("%s",key);
root->Insert(root,key);
}
root->build(root);
scanf("%s",dir);
printf("%d/n",root->query(dir,root));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: