hdu 1251 hud2222 AC自动机

  1 /*前缀查询以及关键词包含个数
  2  *此代码主函数仅用于前缀查询及hdu1251
  3  *用于hdu2222时需要更改主函数以及有注释的地方
  4  */
  5 #include <iostream>
  6 #include <cstring>
  7 #include <string>
  8 #include <cstdio>
  9 #include <queue>
 10 using namespace std;
 11 /*字典树数据结构*/
 12 struct node{
 13     int flag;
 14     node *fail;
 15     node *next[26];
 16     node(){
 17         flag=0;
 18         fail=NULL;
 19         memset(next,NULL,sizeof(next));
 20     }
 21 };
 22 /*插入关键词keyword*/
 23 void insert(char *keyword,node *root)
 24 {
 25     node *p=root;
 26     for(int i=0;keyword[i];i++)
 27     {
 28         int index=keyword[i]-'a';
 29         if(p->next[index]==NULL)
 30         {
 31             p->next[index]=new node();
 32         }
 33         /*下面这一行只限于判断前缀时使用*/
 34         p->flag++;
 35         p=p->next[index];
 36     }
 37     /*这里在判重时不能使用++,而直接将其置1*/
 38     p->flag++;
 39 }
 40 /*判断是否存在前缀str并返回含有此前缀的单词个数*/
 41 int check_prefix(char *str,node *root)
 42 {
 43     node *p=root;
 44     for(int i=0;str[i];i++)
 45     {
 46         int index=str[i]-'a';
 47         if(p->next[index]==NULL)
 48         {
 49             return 0;
 50         }
 51         p=p->next[index];
 52     }
 53     return p->flag;
 54 }
 55 /*构造AC自动机*/
 56 void build_ac_automation(node *root)
 57 {
 58     queue<node*> qv;
 59     root->fail=NULL;
 60     qv.push(root);
 61     while(!qv.empty())
 62     {
 63         node *p=NULL;
 64         node *temp=qv.front();
 65         qv.pop();
 66         for(int i=0;i<26;i++)
 67         {
 68             if(temp->next[i]!=NULL)
 69             {
 70                 if(temp==root)
 71                 {
 72                     temp->next[i]->fail=root;
 73                 }
 74                 else
 75                 {
 76                     p=temp->fail;
 77                     while(p!=NULL)
 78                     {
 79                         if(p->next[i]!=NULL)
 80                         {
 81                             temp->next[i]->fail=p->next[i];
 82                             break;
 83                         }
 84                         p=p->fail;
 85                     }
 86                     if(p==NULL)
 87                     {
 88                         temp->next[i]->fail=root;
 89                     }
 90                 }
 91                 qv.push(temp->next[i]);
 92             }
 93         }
 94     }
 95 }
 96 /*搜索str中包含的关键词的个数*/
 97 int seach(char *str,node *root)
 98 {
 99     int i,index,sum=0;
100     node *p=root;
101     for(i=0;str[i];i++)
102     {
103         index=str[i]-'a';
104         while(p->next[index]==NULL&&p!=root)
105         {
106             p=p->fail;
107         }
108         p=p->next[index];
109         if(p==NULL)
110         {
111             p=root;
112         }
113         node *temp=p;
114         while(temp!=root&&temp->flag!=-1)
115         {
116             sum+=temp->flag;
117             temp->flag=-1;
118             temp=temp->fail;
119         }
120     }
121     return sum;
122 }
123 int main()
124 {
125     char keyword[15],str[15];
126     node *root=new node();
127     while(gets(keyword)&&keyword[0])
128     {
129         insert(keyword,root);
130     }
131     while(gets(str))
132     {
133         printf("%d\n",check_prefix(str,root));
134     }
135     return 0;
136 }
posted @ 2012-08-18 12:03  zyh123101  阅读(173)  评论(0编辑  收藏  举报