您的位置:首页 > 其它

【LA4670-Dominating Patterns】AC自动机

2016-07-19 21:55 302 查看
http://acm.hust.edu.cn/vjudge/problem/19224

题意:给定n个单词,一个字符串,问哪些单词在字符串中出现的次数最多。单词aba,文本ababa,则aba出现了2次。

题解:每找到一个记得要顺着fail找到所有单词。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

const int N=160,L=1000010;
char s[L],ss
[110];
int cnt
;
int num,mx,n;
struct node{
int son[30];
int id,fail;
}a[N*110];
queue<int> q;
int maxx(int x,int y){return x>y ? x:y;}

void clear(int x)
{
a[x].id=a[x].fail=0;
memset(a[x].son,0,sizeof(a[x].son));
}

void trie(char *c,int id)
{
int l=strlen(c);
int x=0;
for(int i=0;i<l;i++)
{
int t=c[i]-'a'+1;
if(!a[x].son[t])
{
num++;
clear(num);
a[x].son[t]=num;
}
x=a[x].son[t];
}
a[x].id=id;
}

void buildAC()
{
while(!q.empty()) q.pop();
for(int i=1;i<=26;i++)
if(a[0].son[i]) q.push(a[0].son[i]);
while(!q.empty())
{
int x=q.front();q.pop();
int fail=a[x].fail;
for(int i=1;i<=26;i++)
{
int y=a[x].son[i];
if(y)
{
a[y].fail=a[fail].son[i];
q.push(y);
}
else a[x].son[i]=a[fail].son[i];
}
}
}

void find(char *c)
{
int l=strlen(c);
int x=0;
for(int i=0;i<l;i++)
{
int t=c[i]-'a'+1;
if(!a[x].son[t]) x=0;
else x=a[x].son[t];
int p=x;
while(p)
{
if(a[p].id) cnt[a[p].id]++;
p=a[p].fail;
}
}
}

int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
while(1)
{
scanf("%d",&n);
if(!n) return 0;
num=mx=0;
clear(0);
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
scanf("%s",ss[i]);
trie(ss[i],i);
}
buildAC();
scanf("%s",s);
find(s);
for(int i=1;i<=n;i++) mx=maxx(mx,cnt[i]);
printf("%d\n",mx);
for(int i=1;i<=n;i++)
{
if(mx==cnt[i]) printf("%s\n",ss[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: