题目 意思 就是说给你N个单词 问模式串里面含有多少个单词;
方法 AC 自动机 首先建立好自动机;然后在构建 fail 指针的时候标记一下路径;然后用模式串去匹配的过程中,不要重复匹配;走过的路程就标记,然后就是简单的计数了; AC自动机解决多字符匹配问题时候;很好用;
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
struct date
{
date *next[27],*fail;
bool flag;
int sum;
}tree[512345],*que[512345],*root;
int tail,head,ptr;
date *creat_node( )
{
for( int i = 0; i <= 26; i++ )
tree[ptr].next[i] = NULL;
tree[ptr].fail = NULL;
tree[ptr].flag = false;
tree[ptr].sum = 0;
return &tree[ptr++];
}
void inint( )
{
tail = head = ptr = 0;
root = creat_node( );
}
void insert( char *word )
{
date *temp = root;
while( *word )
{
int num = *word - 'a';
if( temp->next[num] == NULL )
temp->next[num] = creat_node( );
temp = temp->next[num];
word++;
}
temp->sum++;
}
void build_AC( )
{
que[tail++] = root;
while( tail > head )
{
date *temp = que[head++];
for( int i = 0; i < 26; i++ )
if( temp->next[i] != NULL )
{
if( temp == root ) temp->next[i]->fail = root;
else temp->next[i]->fail = temp->fail->next[i];
temp->next[i]->flag = true;
que[tail++] = temp->next[i];
}
else
{
if( temp == root ) temp->next[i] = root;
else temp->next[i] = temp->fail->next[i];
}
}
}
int search( char *word ,int ans )
{
date *temp = root,*p;
while( *word )
{
int num = *word - 'a';
temp = temp->next[num];
p = temp;
while( p != root )
{
if( p->flag )
{
ans += p->sum;
p->flag = false;
}
else break;
p = p->fail;
}
word++;
}
return ans;
}
int main( )
{
char str[55],cha[1123456];
int T,i,j,N;
scanf("%d",&T);
while( T-- )
{
scanf("%d",&N);
inint( );
for( i = 1; i <= N; i++ )
{
scanf("%s",&str);
insert( str );
}
build_AC( );
scanf("%s",cha);
printf("%d\n",search( cha,0 ) );
}
return 0;
}