查找多个串是否在目标串中出现,简单的AC自动机应用。。。
代码:
#include <iostream>
using namespace std;
struct Node{
int next[100];
int fail, flag;
void init(){
for( int i= 0; i< 100; ++i ) next[i]= 0;
fail= -1; flag= 0;
}
};
Node tb[100000];
int n, cnt, m;
char str[10010];
int mark[1010];
void insert( char*s, int d ){
int rt= 0;
while( *s ){
int t= *s- 30;
if( tb[rt].next[t]== 0 ){
tb[++cnt].init();
tb[rt].next[t]= cnt;
}
rt= tb[rt].next[t]; s++;
}
tb[rt].flag= d;
}
int que[100000], head, tail;
void build(){
int q, p;
head= 0, tail= 0, que[0]= 0;
while( head<= tail ){
int now= que[head++];
for( int t= 0; t< 100; ++t )
if( tb[now].next[t] ){
p= tb[now].next[t]; q= tb[now].fail;
while( q!= -1 && !tb[q].next[t] ) q= tb[q].fail;
if( q== -1 ) tb[p].fail= 0;
else tb[p].fail= tb[q].next[t];
que[++tail]= p;
}
}
}
void match( char*s ){
int rt= 0, q, p;
while( *s ){
int t= *s- 30;
if( tb[rt].next[t] ) rt= tb[rt].next[t];
else{
p= tb[rt].fail;
while( p!= -1 && !tb[p].next[t] ) p= tb[p].fail;
if( p== -1 ) rt= 0;
else rt= tb[p].next[t];
}
if( tb[rt].flag ){
mark[ tb[rt].flag ]= 1;
p= tb[rt].fail;
while( p && !mark[ tb[p].flag ] ){
mark[ tb[p].flag ]= 1;
p= tb[p].fail;
}
}
s++;
}
}
int main(){
cnt= 0; tb[0].init();
scanf("%d",&n );
for( int i= 1; i<= n; ++i ){
scanf("%s",str );
insert( str, i );
}
build();
scanf("%d",&m );
int ans= 0;
for( int i= 1; i<= m; ++i ){
for( int j= 0; j<= n; ++j ) mark[j]= 0;
scanf("%s", str );
match( str );
int num= 0;
for( int j= 1; j<= n; ++j ) num+= mark[j];
if( num ){
ans++;
printf("web %d:", i );
for( int j= 1; j<= n; ++j )
if( mark[j] ) printf(" %d", j );
puts("");
}
}
printf("total: %d\n", ans );
return 0;
}