博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模板——AC自动机
阅读量:5244 次
发布时间:2019-06-14

本文共 1571 字,大约阅读时间需要 5 分钟。

传送门:

 

定义nxt[u]=v表示从u开始不断沿着失配边跳到的第一个是标记点的端点v,那么我们再匹配时沿着last跳,每跳到一个last,它就一定对应一个模式串,所以效率是非常高的。

和KMP一样,我们只需检测ch[u][c]和ch[nxt[u]][c]的下一个字符是否相同,即可进行nxt数组的初始化,即:

从0~25枚举c,令v=ch[u][c]

则nxt[v]=ch[nxt[u]][c]。

这个nxt[v]并不能保证ch[u][c]就一定存在,所以还需要一个while循环一直跳直到找到一个ch[u][c]!=0的端点。出现了一个while,既使代码不够优美,又使效率无法保证.

所以我们直接把所有ch[k][c]=0的端点的ch[k][c]直接连向ch[nxt[k]][c],就好像并差集的一个路径压缩,由于Trie是读完所有模式串后建的,所以这个加边并不会影响Trie,这样就不用担心节点是否存在的问题了(无论如何都会在根节点1上停止,我们先创建一个虚拟节点0,把0的26条边都连在1上,令nxt[1]=0,那么后面无论情况再糟最后也只是nxt[x]=1)。

考虑到这是一个Trie树上的递推,所以我们用BFS搞一搞就好了。

 

在查询时,只需对于当前字符串不停跳nxt,判断是否是模式串的结尾即可,因为ch[k][c]=0的端点的ch[k][c]直接连向ch[nxt[k]][c],所以不用担心从前往后枚举文本串的前缀会过长。

1 #include
2 using namespace std; 3 typedef long long ll; 4 const int inf=(int)(2e9); 5 const ll INF=(ll)(5e18); 6 const int N=1000010; 7 8 //nxt:保存最长的后缀字串 9 char s[N];10 int nxt[N],n,ch[N][26],cnt=1;11 int bl[N],ans=0;12 13 void make(char *s)14 {15 int len=strlen(s),u=1;16 for(int i=0;i
q; 29 q.push(1); nxt[1]=0;30 while(!q.empty())31 {32 int u=q.front(); q.pop();33 for(int i=0;i<26;i++)34 {35 if(!ch[u][i]) ch[u][i]=ch[nxt[u]][i];//剪枝 36 else37 {38 int v=ch[u][i];39 nxt[v]=ch[nxt[u]][i];40 q.push(v);41 }42 }43 }44 }45 46 void query(char *s)47 {48 int len=strlen(s),u=1;49 for(int i=0;i
1&&bl[k]!=-1)54 {55 ans+=bl[k];56 bl[k]=-1;//剪枝 57 k=nxt[k];58 }59 u=ch[u][c];60 }61 printf("%d\n",ans);62 }63 64 int main()65 {66 scanf("%d",&n);67 for(int i=1;i<=n;i++)68 {69 scanf("%s",s);70 make(s);71 } 72 bfs();73 scanf("%s",&s);74 query(s);75 return 0;76 }
View Code

 

转载于:https://www.cnblogs.com/Forever-666/p/10738348.html

你可能感兴趣的文章
17.树的子结构
查看>>
D - Mike and strings
查看>>
C++:多维数组的动态分配(new)和释放(delete)
查看>>
c#基础学习(0806)之抽象类实现多态
查看>>
S5PV210根文件系统的制作(一)
查看>>
51NOD 1244 莫比乌斯函数之和
查看>>
[bzoj1923]外星千足虫[高斯消元]
查看>>
centos下同时启动多个tomcat
查看>>
slab分配器
查看>>
分析 PHP大马-php_mof SHELL
查看>>
TCP/IP
查看>>
[推荐] 协同滤波 —— Collaborative Filtering (CF)
查看>>
python中使用中文
查看>>
数据清洗
查看>>
Android 动态加载 (二) 态加载机制 案例二
查看>>
MVC5 + EF6 + Bootstrap3 (10) 数据查询页面
查看>>
Windows下的Eclipse启动出现:a java runtime environment(JRE) or java development kit(JDK) must be.......
查看>>
PLC 通讯
查看>>
【读书笔记】C#高级编程 第三章 对象和类型
查看>>
python之decode、encode及codecs模块
查看>>