zoukankan      html  css  js  c++  java
  • hdu2222-AC自动机

    原来这个玩意就是在trie上跑kmp啊,以前一直以为是什么难得东西。找失配指针,按要求统计个数,注意当匹配了一个串之后顺便顺着失配指针将前缀串一并统计。这是显然的,如果hello匹配成功,那么hell也算成功匹配。

    在构造失配指针时,注意到当前节点的失配指针就是其父亲节点的失配指针(如果指针指向的节点含有当前节点相同的字符)

    失配指针指向的是最长的一个后缀。

    Keywords Search

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 71602    Accepted Submission(s): 24427


    Problem Description
    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
    Wiskey also wants to bring this feature to his image retrieval system.
    Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
    To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
     
    Input
    First line will contain one integer means how many cases will follow by.
    Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
    Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
    The last line is the description, and the length will be not longer than 1000000.
     
    Output
    Print how many keywords are contained in the description.
     
    Sample Input
    1 5 she he say shr her yasherhs
     
    Sample Output
    3
     
    Author
    Wiskey
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAX_N=500005;
      4 const int MAX_SIG=26;
      5 char T[1000006];
      6 struct node{
      7       int next[MAX_SIG];
      8       int fail,cnt;
      9     }AC[MAX_N];
     10 struct aho
     11 {
     12     int size;
     13     int idx(char c){return c-'a';}
     14     void init()
     15     {
     16         for(int i=0;i<MAX_N;++i)
     17         {
     18             memset(AC[i].next,0,sizeof(AC[i].next));
     19             AC[i].fail=AC[i].cnt=0;
     20         }
     21         size=1;
     22     }
     23 
     24     void insert(char *S)
     25     {
     26         int n=strlen(S);
     27         int u=0;
     28         for(int i=0;i<n;++i){
     29             int c=idx(S[i]);
     30             if(!AC[u].next[c]) AC[u].next[c]=size++;
     31                 u=AC[u].next[c];
     32         }
     33         AC[u].cnt++;
     34     }
     35 
     36     void build(){
     37         queue<int> q;
     38         AC[0].fail=-1;
     39         q.push(0);
     40         while(!q.empty()){
     41             int u=q.front();
     42             q.pop();
     43             for(int i=0;i<MAX_SIG;++i)
     44             {
     45                 if(AC[u].next[i]){
     46                     if(!u) AC[AC[u].next[i]].fail=0;
     47                     else{
     48                         int v=AC[u].fail;
     49                         while(v!=-1){
     50                             if(AC[v].next[i]){
     51                                 AC[AC[u].next[i]].fail=AC[v].next[i];
     52                                 break;
     53                             }
     54                             v=AC[v].fail;
     55                         }
     56                         if(v==-1) AC[AC[u].next[i]].fail=0;
     57                     }
     58                     q.push(AC[u].next[i]);
     59                 }
     60             }
     61         }
     62     }
     63     int Get(int u)
     64     {
     65         int res=0;
     66         while(u!=-1){
     67             res=res+AC[u].cnt;
     68             AC[u].cnt=0;
     69             u=AC[u].fail;
     70         }
     71         return res;
     72     }
     73     int match(char *S)
     74     {
     75         int n=strlen(S);
     76         int u=0,res=0;
     77         for(int i=0;i<n;++i)
     78         {
     79             int c=idx(S[i]);
     80             if(AC[u].next[c]) {u=AC[u].next[c];}
     81             else{
     82                 int v=AC[u].fail;
     83                 while(v!=-1&&AC[v].next[c]==0) v=AC[v].fail;
     84                 if(v==-1) u=0;
     85                 else u=AC[v].next[c];
     86             }
     87             if(AC[u].cnt)
     88                 res=res+Get(u);
     89         }
     90         return res;
     91     }
     92 };
     93 int main()
     94 {
     95     int t,i,n;
     96     char s[55];
     97     cin>>t;
     98     for(i=1;i<=t;++i)
     99     {
    100         aho a;
    101         a.init();
    102         cin>>n;
    103         for(int j=1;j<=n;++j){
    104             scanf("%s",s);
    105             a.insert(s);
    106         }
    107         scanf("%s",T);
    108         a.build();
    109         printf("%d
    ",a.match(T));
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    Nginx进阶使用-负载均衡原理及配置实例
    代理服务技术-正向代理、方向代理、透明代理简析
    Docker入门教程-Linux环境安装Nginx及入门使用
    Mybatis进阶使用-一级缓存与二级缓存
    结对第2次作业——WordCount进阶需求
    团队展示
    原型设计(顶会热词统计)
    C++读取文件统计单词个数及频率
    软工实践第一次作业
    课程作业八
  • 原文地址:https://www.cnblogs.com/zzqc/p/8395826.html
Copyright © 2011-2022 走看看