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;
}
下面把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;
}
相关文章推荐
- HDU 3065 病毒侵袭持续中(AC自动机模板)
- [HDU 3065]病毒侵袭持续中[AC自动机][模板题]
- HDU 3065 病毒侵袭持续中(AC自动机模板)
- AC自动机 ( 模板题啊 )——病毒侵袭持续中 ( HDU 3065 )
- hdu 3065 病毒侵袭持续中 ac自动机模板题
- HDU 3065 病毒侵袭持续中(AC自动机 数组模板)
- hdu 3065 病毒侵袭持续中 AC自动机模板题 ,,一A。
- HDU 2222 ac自动机入门模板题
- [AC自动机模板题] HDU 2222 Keywords Search
- hdu 3695 AC自动机模板题
- hdu 2222 AC自动机模板题(指针版+数组版)
- HDU 2222 Keywords Search 【AC自动机(模板题)】
- HDU 2222 Keywords Search 【AC自动机模板】
- hdu 2222 ac自动机模板
- AC自动机 病毒侵袭持续中 HDU - 3065
- HDU 3065 AC自动机
- 【模板练习——AC自动机】Keywords Search HDU - 2222
- hdu 2222 Keywords Search(AC自动机模板)
- HDU 3065 病毒侵袭持续中 AC自动机题解
- HDU 3065 AC自动机