码迷,mamicode.com
首页 > 其他好文 > 详细

HDU - 2222 Keywords Search

时间:2017-08-26 10:20:34      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:比较   with   ace   integer   eof   push   数组实现   one   std   

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.
InputFirst 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.
OutputPrint how many keywords are contained in the description.Sample Input

1
5
she
he
say
shr
her
yasherhs

Sample Output

3

AC自动机裸题,下面给出用指针实现和用数组实现两种方法。指针比较容易理解,但数组不会出现各种奇奇怪怪的玄学问题。
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <queue>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 char str[1000000+100];
  9 
 10 struct node
 11 {
 12     int num;
 13     struct node *next[26];
 14     struct node *fail;
 15     void init()
 16     {
 17         int i;
 18         for(i=0;i<26;i++)
 19             next[i]=NULL;
 20         num=0;
 21         fail=NULL;
 22     }
 23 }*root;
 24 
 25 
 26 node* rt;
 27 int id,len;
 28 
 29 void build()
 30 {
 31     rt=root;
 32     len=strlen(str);
 33     for(int i=0;i<len;i++)
 34     {
 35         id=str[i]-a;
 36         if(rt->next[id]==NULL)
 37         {
 38             rt->next[id]=new node();
 39             rt->next[id]->init();
 40         }    
 41         rt=rt->next[id];
 42     }
 43     rt->num++;
 44 }
 45 
 46 void get_fail()
 47 {
 48     rt=root;
 49     node *son,*temp;
 50     queue<node *> q;
 51     q.push(rt);
 52     while(!q.empty())
 53     {
 54         temp=q.front();
 55         q.pop();
 56         for(int i=0;i<26;i++)
 57         {
 58             son=temp->next[i];
 59             if(son!=NULL)
 60             {
 61                 if(temp==root)
 62                     son->fail=root;
 63                     else
 64                     {
 65                         rt=temp->fail;
 66                         while(rt)
 67                         {
 68                             if(rt->next[i])
 69                             {
 70                                 son->fail=rt->next[i];
 71                                 break;
 72                             }
 73                             rt=rt->fail;
 74                         }
 75                         if(!rt)
 76                             son->fail=root;
 77                     }
 78                 q.push(son);
 79             }
 80         }
 81     }
 82 }
 83 
 84 int querry()
 85 {
 86     rt=root;
 87     len=strlen(str);
 88     node *temp;
 89     int ans=0;
 90     for(int i=0;i<len;i++)
 91     {
 92         id=str[i]-a;
 93         while(!rt->next[id]&&rt!=root)
 94             rt=rt->fail;
 95         rt=rt->next[id];
 96           if(!rt)
 97               rt=root;
 98           temp=rt;
 99           while(temp!=root)
100           {
101               if(temp->num>=0)
102             {
103                 ans+=temp->num;
104                 temp->num=-1;    
105             }    
106             else
107                 break;
108             temp=temp->fail;
109         }
110     }
111     return ans;
112 }
113 
114 int main()
115 {
116     int T;
117     scanf("%d",&T);
118     while(T--)
119     {
120         int n;
121         root=new node;
122         root->init();
123         scanf("%d",&n);
124         getchar();
125         for(int i=0;i<n;i++)
126         {
127             gets(str);
128             build();            
129         }
130         get_fail();
131         gets(str);
132         printf("%d\n",querry());    
133     }
134     return 0;
135 }
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<queue>
  6 using namespace std;
  7 
  8 const int N=10100,L=1000100;
  9 char s[L];
 10 int num,n;
 11 struct node{
 12     int son[30];
 13     int fail,cnt;
 14 }a[N*60];
 15 queue<int> q;
 16 
 17 void clear(int x)
 18 {
 19     a[x].cnt=0;
 20     a[x].fail=0;
 21     memset(a[x].son,0,sizeof(a[x].son));
 22 }
 23 
 24 void trie(char *c)
 25 {
 26     int l=strlen(c);
 27     int x=0;
 28     for(int i=0;i<l;i++)
 29     {
 30         int t=c[i]-a+1;
 31         if(!a[x].son[t])
 32         {
 33             num++;
 34             clear(num);
 35             a[x].son[t]=num;
 36         }
 37         x=a[x].son[t];
 38     }
 39     a[x].cnt++;
 40 }
 41 
 42 void buildAC()
 43 {
 44     while(!q.empty()) q.pop();
 45     for(int i=1;i<=26;i++)
 46         if(a[0].son[i]) q.push(a[0].son[i]);
 47     while(!q.empty())
 48     {
 49         int x=q.front();q.pop();
 50         int fail=a[x].fail;
 51         for(int i=1;i<=26;i++) 
 52         {
 53             int y=a[x].son[i];
 54             if(y)
 55             {
 56                 a[y].fail=a[fail].son[i];
 57                 q.push(y);
 58             }
 59             else a[x].son[i]=a[fail].son[i];
 60         }
 61     }
 62 }
 63 
 64 int find(char *c)
 65 {
 66     int l=strlen(c);
 67     int x=0,ans=0;
 68     for(int i=0;i<l;i++)
 69     {
 70         int t=c[i]-a+1;
 71         while(x && !a[x].son[t]) x=a[x].fail;        
 72         x=a[x].son[t];
 73         int p=x;
 74         while(p && a[p].cnt!=-1)
 75         {
 76             ans+=a[p].cnt;
 77             a[p].cnt=-1;
 78             p=a[p].fail;
 79         }
 80     }
 81     return ans;
 82 }
 83 
 84 int main()
 85 {
 86     int T;
 87     scanf("%d",&T);
 88     while(T--)
 89     {
 90         scanf("%d",&n);
 91         num=0;
 92         clear(0);
 93         for(int i=1;i<=n;i++)
 94         {
 95             scanf("%s",s);
 96             trie(s);
 97         }
 98         buildAC();
 99         scanf("%s",s);
100         printf("%d\n",find(s));
101     }
102     return 0;
103 }

 



HDU - 2222 Keywords Search

标签:比较   with   ace   integer   eof   push   数组实现   one   std   

原文地址:http://www.cnblogs.com/xibeiw/p/7434415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!