AC自动机模板
2013-04-20 18:26
225 查看
每个节点只访问一次。
无限次访问的模板
//子树节点是在插入时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; }
相关文章推荐
- (模板)AC自动机
- AC自动机 模板 hdu 2222
- HDU2222 Keywords Search(AC自动机模板)
- Match:Keywords Search(AC自动机模板)(HDU 2222)
- hdu 1277 全文检索(ac自动机模板)
- AC自动机模板及基础例题小结
- HDOJ 2222.Keywords Search(AC自动机模板)
- hdu 2222 ac自动机更新模板 for onSite contest
- ac自动机模板(hdu2222)
- ac自动机 模板
- AC自动机(模板题)hdu2896
- P3808 【模板】AC自动机(简单版)
- BZOJ 3172 [Tjoi2013] 单词 [AC自动机模板]
- HDU 2222 (AC自动机模板)
- AC自动机模板先存着,还不会...
- 【AC自动机】HDU中模板题
- hdu 2222 ac自动机入门题 可以做模板
- HDU2222【AC自动机(基础·模板)】
- hdu 2222 ac自动机模板
- hdu 2222 AC自动机模板题