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

HDU 2222 Keywords Search (AC自动机)

时间:2015-05-28 21:14:05      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

 

题意:给一堆关键字(单词),再给一串,求此串中出现几次关键字。(多模式串匹配)

思路:以关键字建立trie树,设置好fail指针,就可以进行求出现次数了。 

 

内存超了!!!开数组也超,开链表都超。。。我去

技术分享
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1000000+100;
  4 char tar[N];
  5 int len, p, q;
  6 string str;
  7 struct node
  8 {
  9     int flag;  //终止标志
 10     node* s[26];   //指向孩子的指针
 11     node* fail;
 12 }a[500001];
 13 
 14 deque<node*> que;
 15 node *create()
 16 {
 17     node* tmp=&a[q++];
 18     //node* tmp=new(node);
 19     for(int i=0; i<26; i++)    tmp->s[i]=0;
 20     tmp->flag=0;
 21     tmp->fail=0;
 22     return tmp;
 23 }
 24 
 25 void input(int p, node *t)
 26 {
 27     if(!t->s[str[p]-a])    t->s[str[p]-a]=create();
 28     node* tmp=t->s[str[p]-a];
 29     if(++p>=len)  //结束
 30     {
 31         tmp->flag++;
 32         return;
 33     }
 34     input(p, tmp);
 35 }
 36 
 37 void BFS(node* t)
 38 {
 39     que.clear();
 40     for(int i=0; i<26; i++)  //先处理第2层的
 41         if(t->s[i])
 42         {
 43             que.push_back(t->s[i]);
 44             t->s[i]->fail=t;
 45         }
 46 
 47     while(!que.empty())
 48     {
 49         int siz=que.size();
 50         while(siz--)    //处理一层
 51         {
 52             node *tmp=que.front();
 53             que.pop_front();
 54             for(int i=0; i<26; i++)  //处理此结点的每个孩子
 55             {
 56                 if(tmp->s[i])
 57                 {
 58                     que.push_back(tmp->s[i]);
 59                     node *k=tmp->fail;  //k和当前结点相同
 60                     while( k!=t && !k->s[i] )
 61                         k=k->fail;
 62 
 63                     if(k==t && !k->s[i])    tmp->s[i]->fail=t;
 64                     else    tmp->s[i]->fail=k->s[i];
 65                 }
 66             }
 67 
 68         }
 69     }
 70 }
 71 
 72 int search(int p, node* t)
 73 {
 74     len=strlen(tar);
 75     node *temp=t;
 76     int cnt=0;
 77     while(p<len)
 78     {
 79         if(temp->flag) //判断是否为匹配
 80         {
 81             cnt+=temp->flag;
 82             temp->flag=0;
 83         }
 84         if(tar[p]<a||tar[p]>z)  //非法字符
 85         {
 86             temp=t;
 87             continue;
 88         }
 89         if(temp->s[tar[p]-a]) //继续往下匹配
 90         {
 91             temp=temp->s[tar[p]-a];
 92             p++;
 93         }
 94         else
 95         {
 96             if(temp==t)    p++;
 97             else    temp=temp->fail;    //匹配失败了
 98         }
 99     }
100     return cnt;
101 }
102 
103 int main()
104 {
105     //freopen("e://input.txt","r",stdin);
106     int t, n;
107     scanf("%d",&t);
108     while(t--)
109     {
110         q=0;
111         node *tree=create();
112         tree->fail=tree;
113         scanf("%d",&n);
114         for(int i=0; i<n; i++)  //构建字典树
115         {
116             cin>>str;
117             len=str.size();
118             input(0,tree);
119         }
120         BFS(tree);  //设置fail指针
121         scanf("%s",tar);
122         printf("%d\n",search(0, tree));
123     }
124 
125     return 0;
126 }
MLE代码

 

HDU 2222 Keywords Search (AC自动机)

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4536870.html

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