HDU 2222 模板题
题目 意思 就是说给你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; }