您的位置:首页 > 其它

hdu 5384 Danganronpa(基础AC自动机)

2015-09-10 20:35 309 查看
题意:多个模式串和多个待匹配串,有n个待匹配串,有m个模式串,求每个待匹配串对于所有模式串的匹配个数;

思路:1、与最裸的ac自动机的区别在于讯问后的叶子节点的count值会改变,在每次询问时count值不要清零;

2、对于多个串的保存直接用二维数组;

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX=26;
int n,m;
typedef struct Trie_Node
{
struct Trie_Node *fail;//失败指针
struct Trie_Node *next[MAX];//26子节点
int count;//单词最后一个结点的计数
}Trie,tree;
Trie *Q[500010];//队列,用于bfs构造
char keyword[55];
char str[1000010];
char num[100005][10004];
int head,tail;//队列的头和尾

void insert(Trie *root,char *word)
{
Trie *p=root;
int i=0;
while(word[i]!='\0')
{
if(p->next[word[i]-'a']==NULL)
{
Trie *temp=new Trie;
for(int j=0;j<MAX;j++)
temp->next[j]=NULL;
temp->count=0;
temp->fail=NULL;
p->next[word[i]-'a']=temp;
}
p=p->next[word[i]-'a'];
i++;
}
p->count++;
}
void build_ac(Trie *root)
{
root->fail=NULL;
head=tail=0;
Q[head++]=root;
while(head!=tail)
{
Trie *temp=Q[tail++];
Trie *p=NULL;
for(int i=0;i<MAX;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;
}
Q[head++]=temp->next[i];
}
}
}
}
int query(Trie *root)
{
int i=0;
int cnt=0;
int len=strlen(str);
Trie *p=root;
int index;
while(str[i])
{
index=str[i]-'a';
while(p->next[index]==NULL&&p!=root)p=p->fail;
p=p->next[index];
if(p==NULL)p=root;
Trie *temp=p;
while(temp!=root)
{
cnt+=temp->count;
//temp->count=0;
temp=temp->fail;
}
i++;
}
return cnt;
}
void del(Trie *root)
{
for(int i=0;i<MAX;i++)
if(root->next[i]!=NULL)
del(root->next[i]);
free(root);
}
int main()
{
int T,len;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",num[i]);
}
Trie *root=new Trie;
root->count=0;
root->fail=NULL;
for(int i=0;i<MAX;i++)
root->next[i]=NULL;
for(int i=0;i<m;i++)
{
scanf("%s",&keyword);
insert(root,keyword);
}
build_ac(root);
for(int i=0;i<n;i++){
strcpy(str,num[i]);
printf("%d\n",query(root));
}
del(root);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: