AC自动机模板
来源:互联网 发布:串口助手软件下载 编辑:程序博客网 时间:2024/05/29 19:45
在串里找单词实际上是一个一个找,找到一个字符一样,加上他的count值,然后通过失败指针返回根节点,
所以要用一个temp来这样做,p的指针始终通过主串来改变,找到一个字符相等,p不变,temp变,再比较p
的儿子与主串中下一个字符,重复以上操作
#include<iostream>#include<queue>#include<cstring>#include<cstdio>#define maxn 1000005using namespace std;int head,tail;//队列头尾指针struct node{ node *fail; //fail指针表指向与与该元素相同的节点或根节点 node *next[26];//26个小写字母 int count;//记录每一个单词的末尾 node() //结构体重载 { fail =NULL; memset(next,0,sizeof(next)); count = 0 ; }}*q[maxn];node *root;void insert(char s[])//建立字典树,这里就是26叉树{ node *p=root; int len =strlen(s); for(int i=0;i<len;i++) { int id=s[i]-'a'; if(p->next[id]==NULL) p->next[id]=new node();//若根节点下当前字符没有出现过,新建里一个当前字符的节点 p=p->next[id];//p指向当前节点 } p->count++;//单词末尾的次数加1,代表右边出现过几个最后一个字符为末尾元素的子串}void build_ac()//建立fail指针{ node *p,*temp=NULL; q[tail++]=root;//根节点先入队 while(head!=tail) //队列不为空时 { p=q[head++];//出队 for(int i=0;i<26;i++)//26叉树,寻找单词的首字母 { if(p->next[i])//不为空就表示该字符存在 { if(p==root)//当孩子的父亲为根节点,也就是该字符位于第一层 p->next[i]->fail=root; //直接将失败指针指向根节点 else { temp = p->fail;//否则先记录当前节点的失败指针 while(temp!=NULL)//当指向为空时,跳出,这里有个误区,不能在temp等于root时跳出,因为可能根节点的儿子中存在与当前节点儿子相同的字符 { if(temp->next[i]) //如果当前节点指向的失败指针的儿子与当前节点的儿子相同 { p->next[i]->fail=temp->next[i];//将当前节点的儿子的失败指针指向它 break; } temp=temp->fail;//否则一直找与当前节点相同的元素 } if(temp==NULL) p->next[i]->fail=root;//找不到,则直接把当前节点的儿子指向根节点 } q[tail++]=p->next[i];//将当前节点的儿子入队以便在下一层完成他儿子的失败指针 } } }}int query(char s[])//查找有几个单词出现{ node *p=root,*temp; int len = strlen(s); int res=0; for(int i=0;i<len;i++) { int id =s[i]-'a'; while(p->next[id]==NULL&&p!=root) p=p->fail;//如果p位于字典树一边的末尾,跳转到与p儿子相同元素的,若没有跳转到根节点 p=p->next[id];//p指向当前元素 if(p==NULL) p=root;//如果这样的字符不存在,则指向根节点 temp = p;//p不能改变,否则下一个字符就无法比较 while(temp!=root&&temp->count!=-1)//终点就是回到根而且再找的过程中找到一个必须标记为找过,否则会重复加 { res+=temp->count;//加上当前字符的count值 temp->count=-1; //标记为访问过 temp=temp->fail; //不断找同的元素。直到回到根 } } return res;}
0 0
- 【AC自动机】AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板 hdu2222
- AC自动机模板
- AC自动机模板
- 数据结构--AC自动机--模板
- ac自动机模板
- AC自动机模板
- AC自动机模板
- hdu2222 ac自动机模板
- ac自动机模板。。。。。
- AC自动机模板 LA4670
- AC自动机模板
- C++基础::关于区间端点的问题
- 杭电1069--Monkey and Banana 子序列,dp
- lamp 环境搭建遇到的问题
- kworker内核工作队列详解
- codeforces GYM 100792H
- AC自动机模板
- 我的iOS学习历程 - UIView和UILabel
- 编写方法,完成指定文件的复制和剪切;使用BufferedReader和BufferedWriter完成。
- hdu1159 Common Subsequence (最长公共子序列)
- 关于兔子问题(斐波那契数)的Java实现--采用面向对象的方式
- muduo库阅读(22)——文件压缩类
- LintCode- 翻转字符串
- python 爬虫及multiprocessing包——多线程爬取并解析百度贴吧某贴小trick
- 常见问题时间复杂度(1)