您的位置:首页 > 其它

hdu2222 ac自动机裸题

2016-07-18 16:54 260 查看
前几天讲了ac自动机,今天才a了第一道模板题.(o(╯□╰)o),我还是太弱了(毕竟蒟蒻).

问题难度很小,我注释的很详细了,应该能懂吧

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int t,tou,tail,n;
char s[55],s1[100005];
struct node{
node *fail;
node *net[26];
int ci;
node()
{
fail=NULL;
ci=0;
for (int i=0;i<26;i++)
{
net[i]=NULL;
}
}
}*q[500005];
node *root;
void trie_build(char *s) //建立Trie
{
int temp, len;
node *p = root;
len = strlen(s);
for(int i = 0; i < len; ++i)
{
temp = s[i] - 'a';
if(p->net[temp] == NULL)
p->net[temp] = new node();
p = p->net[temp];
}
p->ci++;
}
void ac_build()
{
q[tail++]=root;//初始化
while(tou!=tail)
{
node *p=q[tou++];
node *temp=NULL;//pop()
for(int i = 0; i < 26; ++i)
{
if(p->net[i] != NULL)
{
if(p == root) //第一个元素fail必指向根
p->net[i]->fail = root;
else
{
temp = p->fail; //失败指针
while(temp != NULL) //匹配为空 or 找到匹配
{
if(temp->net[i] != NULL)
{
p->net[i]->fail = temp->net[i];
break;
}
temp = temp->fail;
}
if(temp == NULL) //为空则从头匹配
p->net[i]->fail = root;
}
q[tail++] = p->net[i]; //入队
}
}
}
}
int query()
{
node *p=root;
int len=strlen(s1);
int ans=0;
for(int i=0;i<len;i++)
{
int temp=s1[i]-'a';
while (p->net[temp]==NULL&&p!=root)//跳转到fail指针
{
p=p->fail;
}
p=p->net[temp];
if (p==NULL) p=root;
node *w=p;
while (w!=root&&w->ci!=-1)
{
ans+=w->ci;
w->ci=-1;
w=w->fail;
}
}
return ans;
}
void readdata()
{

int t, num;
scanf("%d", &t);
while(t--)
{
tou= tail = 0;
root = new node();
scanf("%d", &num);
getchar();
for(int i = 0; i < num; ++i)
{
gets(s);
trie_build(s);
}
ac_build();
scanf("%s", s1);
printf("%d\n", query());
}
}
int main()
{
readdata();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ac自动机