您的位置:首页 > 产品设计 > UI/UE

HDU 3065 AC自动机模板题

2012-03-24 21:19 399 查看
最后一道模板题。

下面把AC自动机小结一下。请看新文章.....

这题如果只开26的next的数组的话。

在查询大串时,要注意的if( s[i] )当不符合条件时,不能浅显的continue,而要把p=root;

不然..... 那些在A-Z之外的字符会直接略去,相当于大串中没有A-Z之外的字符,结果可想而知!!

#include<iostream>
#include<string>
#include<cstdio>
#define MAX 26
using namespace std;

char str[2222222];
char str0[1111][55];
int cnt[1111],queue[555555];
int root,tot;

struct node
{
int fail,id;
int next[MAX];
void init()
{
memset( next,0,sizeof(next) );
fail=-1,id=0;
}
}Tire[555555];

void init()
{
root=tot=0;
Tire[root].init();
memset( cnt,0,sizeof(cnt) );
}

void insert( char *s,int id )
{
int i=0,k;
int p=root;
while( s[i] )
{
k=s[i++]-'A';
if( !Tire[p].next[k] )
{
Tire[++tot].init();
Tire[p].next[k]=tot;
}
p=Tire[p].next[k];
}
Tire[p].id=id;
}

void build_ac_automation()
{
int head,tail;
head=tail=0;
queue[tail++]=root;
while( head<tail )
{
int cur=queue[head++];
for( int i=0;i<MAX;i++ )
{
if( Tire[cur].next[i] )
{
int son=Tire[cur].next[i];
int p=Tire[cur].fail;
if( cur==root )
Tire[son].fail=root;
else
Tire[son].fail=Tire[p].next[i];
queue[tail++]=son;
}
else
{
int p=Tire[cur].fail;
if( cur==root )
Tire[cur].next[i]=root;
else
Tire[cur].next[i]=Tire[p].next[i];
}
}
}
}

void query( char *s )
{
int i=0,k;
int p=root;
while( s[i] )
{
k=s[i++]-'A';
if( k<0||k>25 )
{
p=root;
continue;
}
while( !Tire[p].next[k]&&p!=root )
p=Tire[p].fail;
p=Tire[p].next[k];
if( p==-1 ) p=0;
int temp=p;
while( temp!=root )
{
cnt[Tire[temp].id]++;
temp=Tire[temp].fail;
}
}
}

int main()
{
int N;
while( scanf( "%d\n",&N )!=EOF )
{
init();
for( int i=1;i<=N;i++ )
{
scanf( "%s",&str0[i] );
insert(str0[i],i);
}
build_ac_automation();
scanf( "%s",&str );
query(str);
for( int i=1;i<=N;i++ ){
if( cnt[i] )
printf( "%s: %d\n",str0[i],cnt[i] );
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  insert query build