您的位置:首页 > 其它

hdu2222Keywords Search(AC自动机模板题)

2017-08-19 09:57 225 查看
题意:

给你n个模板串,一个文本串,求有几个模板串出现在文本串中。

思路:

如果暴力n次kmp,稳超时。所以把模板串处理一下,设置fail指针(相当与kmp里的next)。ac自动机可以处理多模式匹配,要注意的是,多模式匹配时,匹配到一个串时还可能同时匹配到别的串。

代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;
const int maxn = 1000000+7;
char key[57];
struct node
{
int val;
node *next[26];
node *fail;
};

void ins(node *root,char *p)
{
int len = strlen(p);
int i = 0,id;
while(i<len)
{
id = p[i]-'a';
if(root->next[id]==NULL)
{
node *temp = new node;
temp->fail = NULL;
temp->val = 0;
for(int i = 0;i<26;i++)
temp->next[i] = NULL;
root->next[id] = temp;
}
root = root->next[id];
i++;
}
root->val++;
}

void build(node *root)
{
queue<node*> q;
q.push(root);
while(!q.empty())
{
node *temp = q.front();
q.pop();
for(int i = 0;i<26;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root)
{
temp->next[i]->fail = root;
}
else
{
node *k = temp->fail;
while(k)
{
if(k->next[i]!=NULL)
{
temp->next[i]->fail = k->next[i];
break;
}
k = k->fail;
//cout<<"hh"<<endl;
}
if(!k)
temp->next[i]->fail = root;
}
q.push(temp->next[i]);
}
}
//cout<<q.size()<<endl;
}
}

int add(node *temp) //匹配到当前串的同时,可能还同时会匹配到别的串
{
int sum = 0;
while(temp!=NULL&&temp->val>=0)
{
sum += temp->val;
temp->val = -1;
temp = temp->fail;
}
return sum;
}

int match(node *root,char *str)
{
int cnt = 0;
int len = strlen(str);
int id;
node *p = root;
for(int i = 0;i<len;i++)
{
id = str[i]-'a';
while(p!=root&&p->next[id]==NULL)
p = p->fail;
if(p->next[id]!=NULL)
{
p = p->next[id];
cnt += add(p);
}
}
return cnt;
}

void del(node *root)
{
for(int i = 0;i<26;i++)
if(root->next[i]!=NULL)
del(root->next[i]);
delete root;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
getchar();
node *root = new node;
root->val = 0;
root->fail = NULL;
for(int i = 0;i<26;i++)
root->next[i] = NULL;
for(int i = 0;i<n;i++)
{
scanf("%s",key);
ins(root,key);
}
build(root);
//cout<<"kii"<<endl;
char str[maxn];
scanf("%s",str);
printf("%d\n",match(root,str));
del(root);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: