AC自动机模板
2014-10-07 18:40
281 查看
每个节点只访问一次
无限访问节点
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int kind = 256;
struct node
{
node *fail;
node *next[kind];
int count;
bool visit;
node()
{
fail = NULL;
count = 0;
visit = false;
memset(next,NULL,sizeof(next));
}
};
node* query_temp_que[1111];
void insert(unsigned char *str,node *root,int slen)
{
node *p=root;
int i,index;
for (i=0;i<slen;i++)
{
index = (int)str[i];
if(p->next[index]==NULL) p->next[index]=new node();
p=p->next[index];
}
p->count++;
}
//寻找失败指针
void build_ac_automation(node *root)
{
int i;
queue<node *>Q;
root->fail = NULL;
Q.push(root);
while(!Q.empty())
{
node *temp=Q.front();//q[head++];//取队首元素
Q.pop();
node *p=NULL;
for(i=0; i<kind; i++)
{
if(temp->next[i]!=NULL)//寻找当前子树的失败指针
{
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.push(temp->next[i]);
}
}
}
}
//询问str中包含n个关键字中多少种即匹配
int query(unsigned char *str,node *root,int slen)
{
int i,cnt = 0,index;
int head,tail;
head=tail=0;
node *p = root;
for (i=0;i<slen;i++)
{
index = (int)str[i];
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->visit)//寻找到当前位置为止是否出现病毒关键字
{
cnt+=temp->count;
temp->visit=true;
query_temp_que[tail++]=temp;
temp=temp->fail;
}
}
while (head<tail)
{
node* cur=query_temp_que[head++];
cur->visit=false;
}
return cnt;
}
//子树节点是在插入时new的, //寻找失配指针中使用的队列是直接调用STL的 const int kind = 26; struct node { node *fail; node *next[kind]; int count;//记录当前前缀是完整单词出现的个数 node() { fail = NULL; count = 0; memset(next,NULL,sizeof(next)); } }; void insert(char *str,node *root) { node *p=root; int i=0,index; while(str[i]) { index = str[i]-'a'; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count++; } //寻找失败指针 void build_ac_automation(node *root) { int i; queue<node *>Q; root->fail = NULL; Q.push(root); while(!Q.empty()) { node *temp = Q.front();//q[head++];//取队首元素 Q.pop(); node *p = NULL; for(i=0; i<kind; i++) { if(temp->next[i]!=NULL)//寻找当前子树的失败指针 { 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.push(temp->next[i]); } } } } //询问str中包含n个关键字中多少种即匹配 int query(node *root) { int i = 0,cnt = 0,index,len; len = strlen(str); node *p = root; 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; node *temp = p; while(temp!=root&&temp->count!=-1)//寻找到当前位置为止是否出现病毒关键字 { //if(temp->count!=0) cnt+=temp->count; temp->count=-1; temp=temp->fail; } i++; } return cnt; }
无限访问节点
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int kind = 256;
struct node
{
node *fail;
node *next[kind];
int count;
bool visit;
node()
{
fail = NULL;
count = 0;
visit = false;
memset(next,NULL,sizeof(next));
}
};
node* query_temp_que[1111];
void insert(unsigned char *str,node *root,int slen)
{
node *p=root;
int i,index;
for (i=0;i<slen;i++)
{
index = (int)str[i];
if(p->next[index]==NULL) p->next[index]=new node();
p=p->next[index];
}
p->count++;
}
//寻找失败指针
void build_ac_automation(node *root)
{
int i;
queue<node *>Q;
root->fail = NULL;
Q.push(root);
while(!Q.empty())
{
node *temp=Q.front();//q[head++];//取队首元素
Q.pop();
node *p=NULL;
for(i=0; i<kind; i++)
{
if(temp->next[i]!=NULL)//寻找当前子树的失败指针
{
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.push(temp->next[i]);
}
}
}
}
//询问str中包含n个关键字中多少种即匹配
int query(unsigned char *str,node *root,int slen)
{
int i,cnt = 0,index;
int head,tail;
head=tail=0;
node *p = root;
for (i=0;i<slen;i++)
{
index = (int)str[i];
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->visit)//寻找到当前位置为止是否出现病毒关键字
{
cnt+=temp->count;
temp->visit=true;
query_temp_que[tail++]=temp;
temp=temp->fail;
}
}
while (head<tail)
{
node* cur=query_temp_que[head++];
cur->visit=false;
}
return cnt;
}
相关文章推荐
- HDU2222(AC自动机模板题)
- HDU 2222 Keywords Search (AC自动机模板题)
- HDU 2222 Keywords Search (AC自动机模板题)
- AC自动机模板
- AC自动机模板
- AC自动机模板
- HDU 2222 Keywords Search (AC自动机模板题)
- 【COCI2012 Task 5】T6 poplocavanje ([JZOJ3172]贴瓷砖)(AC自动机模板)
- ac自动机模板
- hdu:2222:Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search (AC自动机模板题)
- 模板_AC自动机
- AC 自动机(模板)
- 邝斌的ACM模板(AC 自动机)
- (AC自动机)模板
- hdu 2222 裸的AC自动机静态模板
- 【模板】AC自动机
- hdu 2222 Keywords Search(ac自动机模板题)
- HDU 2222 Keywords Search(AC自动机模板题)
- HDU3695(AC自动机模板题)