题意 就是N个病毒,一个 匹配串,然后让你从这匹配串里面去找病毒出现的次数;
方法 如果匹配 则往下走,如果不匹配,或者没有字符越界,回到根节点;
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> using namespace std; struct date { date *next[26],*fail; int tab; }tree[51234],*que[51234],*root; int tail,head,ptr,res[1123]; char str[2123456],sss[2123456],cha[1123][55]; date *creat_node( ) { for( int i = 0; i < 26; i++ ) tree[ptr].next[i] = NULL; tree[ptr].fail = NULL; tree[ptr].tab = 0; return &tree[ptr++]; } void inint( ) { tail = head = ptr = 0; root = creat_node(); } void insert( char *word,int tab ) { 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->tab = tab; } 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]; que[tail++] = temp->next[i]; } else { if( temp == root ) temp->next[i] = root; else temp->next[i] = temp->fail->next[i]; } } } void query( char *word ) { date *patten,*temp = root; while( *word ) { int num = *word - 'A'; if( num < 0 || num > 25 ) { temp = root;word++; continue; } temp = temp->next[num]; patten = temp; while( patten != root ) { if( patten->tab ) res[patten->tab]++; patten = patten->fail; } word++; } } int main( ) { int N,i,t; while( scanf("%d",&N) != EOF ) { inint(); for( i = 1; i <= N; i++ ) { scanf("%s",&cha[i]); insert( cha[i],i ); } build_AC(); scanf("%s",&sss); memset( res,0,sizeof(res) ); query( sss ); for( i = 1; i <= N; i++ ) if( res[i] ) printf("%s: %d\n",cha[i],res[i]); } return 0; }