您的位置:首页 > 其它

hdu 1251 hud2222 AC自动机

2012-08-18 12:03 411 查看
/*前缀查询以及关键词包含个数
*此代码主函数仅用于前缀查询及hdu1251
*用于hdu2222时需要更改主函数以及有注释的地方
*/
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
using namespace std;
/*字典树数据结构*/
struct node{
int flag;
node *fail;
node *next[26];
node(){
flag=0;
fail=NULL;
memset(next,NULL,sizeof(next));
}
};
/*插入关键词keyword*/
void insert(char *keyword,node *root)
{
node *p=root;
for(int i=0;keyword[i];i++)
{
int index=keyword[i]-'a';
if(p->next[index]==NULL)
{
p->next[index]=new node();
}
/*下面这一行只限于判断前缀时使用*/
p->flag++;
p=p->next[index];
}
/*这里在判重时不能使用++,而直接将其置1*/
p->flag++;
}
/*判断是否存在前缀str并返回含有此前缀的单词个数*/
int check_prefix(char *str,node *root)
{
node *p=root;
for(int i=0;str[i];i++)
{
int index=str[i]-'a';
if(p->next[index]==NULL)
{
return 0;
}
p=p->next[index];
}
return p->flag;
}
/*构造AC自动机*/
void build_ac_automation(node *root)
{
queue<node*> qv;
root->fail=NULL;
qv.push(root);
while(!qv.empty())
{
node *p=NULL;
node *temp=qv.front();
qv.pop();
for(int i=0;i<26;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==root)
{
temp->next[i]->fail=root;
}
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
{
temp->next[i]->fail=root;
}
}
qv.push(temp->next[i]);
}
}
}
}
/*搜索str中包含的关键词的个数*/
int seach(char *str,node *root)
{
int i,index,sum=0;
node *p=root;
for(i=0;str[i];i++)
{
index=str[i]-'a';
while(p->next[index]==NULL&&p!=root)
{
p=p->fail;
}
p=p->next[index];
if(p==NULL)
{
p=root;
}
node *temp=p;
while(temp!=root&&temp->flag!=-1)
{
sum+=temp->flag;
temp->flag=-1;
temp=temp->fail;
}
}
return sum;
}
int main()
{
char keyword[15],str[15];
node *root=new node();
while(gets(keyword)&&keyword[0])
{
insert(keyword,root);
}
while(gets(str))
{
printf("%d\n",check_prefix(str,root));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: