您的位置:首页 > 其它

hdu 2222 Keywords Search(ac自动机入门题)

2016-07-16 10:26 316 查看
/************************************************************
题目:       Keywords Search(hdu 2222)
链接:       http://acm.hdu.edu.cn/showproblem.php?pid=2222 算法:       ac自动机
算法思想:   多个字符串匹配,也就是相当于多个kmp
*************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;

const int mx=1000000;
char str[mx];
struct Node
{
int data;
int fail;
int count;
int next[26];
void init(int a)
{
data=a;
fail=0;
count=0;
fill(next,next+26,-1);
}
};
Node tree[mx];
int cut;

void insert(char *s)
{
int p=0;
for (int i=0;s[i];i++)
{
int k=s[i]-'a';
if (tree[p].next[k]==-1)
{
tree[cut].init(k);
tree[p].next[k]=cut++;
}
p=tree[p].next[k];
}
tree[p].count++;
}

void ac()
{
int k=0;
queue<Node>q;
q.push(tree[0]);
while (!q.empty())
{
Node u=q.front();
q.pop();
for (int i=0;i<26;i++)
{
if (u.next[i]!=-1)
{
if (u.data==-1) tree[u.next[i]].fail=0;
else
{
int v=u.fail;
while (v&&tree[v].next[i]==-1) v=tree[v].fail;
tree[u.next[i]].fail=max(tree[v].next[i],0);
}
q.push(tree[u.next[i]]);
}
}
}
}

int getans(char *s)
{
int k=0,ans=0;
for (int i=0;s[i];i++)
{
int x=s[i]-'a';
while (k&&tree[k].next[x]==-1) k=tree[k].fail;
k=tree[k].next[x];
if (k==-1) {k=0;continue;}
int j=k;
while (tree[j].count)
{
ans+=tree[j].count;
tree[j].count=0;
j=tree[j].fail;
}
ans+=tree[tree[j].fail].count;
tree[tree[j].fail].count=0;
}
return ans;
}

int main()
{
int t;
scanf("%d",&t);
while (t--)
{
cut=0;
tree[cut++].init(-1);
int n;
scanf("%d",&n);
while (n--)
{
scanf("%s",str);
insert(str);
}
ac();
scanf("%s",str);
printf("%d\n",getans(str));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: