hdu3065 ac自动机

来源:互联网 发布:网络水晶头品牌 编辑:程序博客网 时间:2024/05/24 03:32


3
AA
BB
CC
ooxxCC%dAAAoen....END
 


Sample Output
AA: 2
CC: 1

重复记录


const  int  maxn = 1000008  ;struct TrieNode{       TrieNode *fail ;       TrieNode *next[26] ;       int id ;       TrieNode(){           fail = NULL ;           id = 0 ;           for(int i = 0 ; i < 26 ; i++) next[i] = NULL ;       }};void  Insert(TrieNode *root , char *s , int id){      TrieNode *now = root  ;      while(*s){          int k = *s - 'A' ;          if(now->next[k] == NULL)               now->next[k] = new TrieNode() ;          now = now->next[k] ;          s++ ;      }      now->id = id ;}TrieNode *que[maxn] ;void makeAC(TrieNode *root){     int head = 0 , tail = -1 ;     que[++tail] = root ;     while(head <= tail){          TrieNode *now = que[head++] ;          for(int i = 0 ; i < 26 ; i++){              if(now->next[i] != NULL){                  if(now == root)                      now->next[i]->fail = root ;                  else{                      TrieNode *f = now->fail ;                      while(f != NULL){                          if(f->next[i] != NULL){                              now->next[i]->fail = f->next[i] ;                              break ;                          }                          f = f->fail ;                      }                      if(f == NULL)                          now->next[i]->fail = root ;                  }                  que[++tail] = now->next[i] ;              }          }     }}int  vis[2000008] ;void ask(TrieNode *root , char *s){     memset(vis , 0 , sizeof(vis)) ;     TrieNode *now = root ;     int sum = 0 , k  ;     while(*s){          if(*s >= 'A' && *s <= 'Z'){              k = *s - 'A' ;              while(now != root && now->next[k] == NULL)                now = now->fail ;              now = now->next[k] ;              if(now == NULL) now = root ;              TrieNode *f = now ;              while(f != root && f->id > 0){                   vis[f->id]++ ;                   f = f->fail ;              }          }          else  now = root ;          s++ ;     }}char word[1008][58] ;char text[2000008] ;int  main(){     int n , m  , i  ;     while(cin>>n){          TrieNode *root = new TrieNode() ;          for(i = 1 ; i <= n ; i++){              scanf("%s" ,  word[i]) ;              Insert(root , word[i] , i) ;          }          makeAC(root) ;          scanf("%s" , text) ;          ask(root , text) ;          for(i = 1 ; i <= n ; i++){              if(vis[i] > 0)                  printf("%s: %d\n" , word[i] , vis[i]) ;          }     }     return 0 ;}

char  word[1008][58] ;char  text[2000008] ;/*AC-------------*/const  int maxn = 1000*58 ;const  int kind = 128 ;int    next[maxn][kind] ;int    fail[maxn] ;int    id[maxn]   ;struct  AC{        int  root , n ;        int  newnode(){             id[n] = 0 ;             for(int i = 0 ; i < kind ; i++) next[n][i] = -1 ;             return n++ ;        }        void  Init(){              n = 0 ;              root = newnode() ;        }        void  Insert(char *s , int idx){              int now = root  , k ;              while(*s){                   k = *s - ' ' ;                   if(next[now][k] == -1)                       next[now][k] = newnode() ;                   now = next[now][k] ;                   s++ ;              }              id[now] = idx  ;        }        void  makeAc(){              queue<int> q ;              fail[root] = root ;              int now , i ;              for(i = 0 ; i < kind ; i++){                   if(next[root][i] == -1)                       next[root][i] = root ;                   else{                       fail[next[root][i]] =  root ;                       q.push(next[root][i]) ;                   }              }              while(! q.empty()){                   now = q.front() ; q.pop() ;                   for(i = 0 ; i < kind ; i++){                       if(next[now][i] == -1)                           next[now][i] = next[fail[now]][i] ;                       else{                           fail[next[now][i]] = next[fail[now]][i] ;                           q.push(next[now][i]) ;                       }                   }              }        }        int  vis[1008] ;        void ask(char *s , int m){             memset(vis , 0 , sizeof(vis)) ;             int now = root , k  ;             while(*s){                  k = *s - ' ' ;                  now = next[now][k] ;                  int t = now  ;                  while(t != root){                       vis[id[t]]++ ;                       t = fail[t] ;                  }                  s++ ;             }             for(int i = 1 ; i <= m ; i++){                  if(vis[i]) printf("%s: %d\n" , word[i] , vis[i]) ;             }        }}ac ;/*EndAc---------------*/int   main(){      int t , n  , i  , sum  , m ;      while(cin>>n){           ac.Init() ;           for(i = 1 ; i <= n ; i++){                scanf("%s" , word[i]) ;                ac.Insert(word[i] , i) ;           }           ac.makeAc() ;           sum = 0 ;           scanf("%s" , text) ;           ac.ask(text , n) ;      }      return 0 ;}





0 0
原创粉丝点击