算法模板——AC自动机
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法、AC自动机详解。考虑到有时候字典会相当稀疏,所以引入了chi和bro指针进行优化——其原理比较类似于邻接表,这个东西和next数组本质上是一致的,只是chi和bro用于遍历某一节点下的子节点,next用于查询某节点下是否有需要的子节点)
- type
- point=^node;
- node=record
- ex:longint;st:ansistring;
- ct:char;
- fat,jump,chi,bro:point;
- next:array['A'..'Z'] of point;
- end;
- var
- i,j,k,l,m,n:longint;
- head,p:point;
- s1,s2:ansistring;
- function getpoint:point;inline;
- var p:point;c1:char;
- begin
- new(p);
- p^.ex:=;p^.st:='';
- p^.ct:=chr();
- p^.bro:=nil;p^.chi:=nil;
- p^.fat:=nil;p^.jump:=head;
- for c1:='A' to 'Z' do p^.next[c1]:=nil;
- exit(p);
- end;
- procedure ins(s1:ansistring;x:longint);inline;
- var p:point;s2:ansistring;i:longint;
- begin
- p:=head;S2:='';
- for i:= to length(s1) do
- begin
- s2:=s2+s1[i];
- if p^.next[s1[i]]=nil then
- begin
- p^.next[s1[i]]:=getpoint;
- p^.next[s1[i]]^.fat:=p;
- p^.next[s1[i]]^.st:=s2;
- p^.next[s1[i]]^.ct:=s1[i];
- p^.next[s1[i]]^.bro:=p^.chi;
- p^.chi:=p^.next[s1[i]];
- end;
- p:=p^.next[s1[i]];
- end;
- if p^.ex= then p^.ex:=x;
- end;
- procedure linkit;inline;
- var i,j,k,l,f,r:longint;
- d:array[..] of point;
- p,p1,p2:point;
- begin
- f:=;r:=;d[]:=head;
- while f<r do
- begin
- p:=d[f]^.chi;
- while p<>nil do
- begin
- d[r]:=p;
- if d[f]<>head then
- begin
- p1:=d[f]^.jump;
- while p1<>head do
- begin
- if p1^.next[p^.ct]<>nil then break;
- p1:=p1^.jump;
- end;
- if p1^.next[p^.ct]<>nil then p^.jump:=p1^.next[p^.ct];
- end;
- inc(r);
- p:=p^.bro;
- end;
- inc(f);
- end;
- end;
- procedure fit(s1:ansistring);inline;
- var p,p1:point;i:longint;
- begin
- p:=head;
- for i:= to length(s1) do
- begin
- if p^.next[s1[i]]=nil then
- begin
- while (p^.next[s1[i]]=nil) and (p<>head) do p:=p^.jump;
- if p^.next[s1[i]]<>nil then p:=p^.next[s1[i]];
- end
- else p:=p^.next[s1[i]];
- p1:=p;
- while p1<>head do
- begin
- if p1^.ex<> then writeln('No.',p1^.ex,' ',p1^.st,' From:',i-length(p1^.st)+);
- p1:=p1^.jump;
- end;
- end;
- end;
- begin
- readln(n,m);
- head:=getpoint;head^.jump:=head;
- for i:= to n do
- begin
- readln(s1);
- ins(upcase(s1),i);
- end;
- linkit;
- for i:= to m do
- begin
- readln(s1);
- fit(upcase(s1));
- end;
- end.
算法模板——AC自动机的更多相关文章
- [算法模版]AC自动机
[算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义 ...
- 算法竞赛模板 AC自动机
AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...
- 【字符串算法】AC自动机
国庆后面两天划水,甚至想接着发出咕咕咕的叫声.咳咳咳,这些都不重要!最近学习了一下AC自动机,发现其实远没有想象中的那么难. AC自动机的来历 我知道,很多人在第一次看到这个东西的时侯是非常兴奋的.( ...
- luoguP3808[模板]AC自动机(简单版)
传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...
- luoguP3796[模板]AC自动机(加强版)
传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...
- 模板 AC自动机
题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...
- 洛谷.3808/3796.[模板]AC自动机
题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...
- 模板—AC自动机
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct ...
- 模板——AC自动机
传送门:QAQQAQ 定义nxt[u]=v表示从u开始不断沿着失配边跳到的第一个是标记点的端点v,那么我们再匹配时沿着last跳,每跳到一个last,它就一定对应一个模式串,所以效率是非常高的. 和K ...
随机推荐
- LINQ to Sql系列一 增,删,改
首先,我们来了解一下LINQ to sql 是什么,我想从以下几点来做说明. 1,LINQ是从.net framework 3.0开始引入的的语言特性,主要是用来对集合数据进行操作的.2,LINQ t ...
- PHP中目录解析函数
dirname(string path):给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名. 斜线(/)和反斜线(\)都可以用作目录分隔符.在其它环境下是斜线(/). dir ...
- java算法 蓝桥杯 格子位置
问题描述 输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中,与格子(i,j)同行.同列.同一对角线的所有格子的位置. 输入格式 输入共三 ...
- Java错题
加粗为正确答案,绿色为错选答案 1.对于以下代码: for ( int i=0; i<10; i++) System.out.println(i); for循环后,i的值是多少? A.i不再存 ...
- html 一般标签 常用标签 表格
body的属性: bgcolor 页面背景色 background 背景壁纸.图片 text 文字颜色 top ...
- 蓝桥网试题 java 入门训练 A+B问题
---------------------------------------------------------------------------------------------------- ...
- HDU 2080 夹角有多大II
夹角有多大II Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- DB2_自动生成值
生成数字序列的两种方法 在 DB2 中可以用两种方法自动生成一个数字序列: 定义带有 IDENTITY 属性的列. 创建 SEQUENCE 对象. IDENTITY 列 当用 IDENTITY 属性定 ...
- docker - 容器里安装ssh
docker安装ssh 通过命令行安装 pull ubuntu镜像 docker pull ubuntu:latest 启动并进入bash docker run -it -d ubuntu:laste ...
- 原生js实现轮播图
原生js实现轮播图 很多网站上都有轮播图,但找到一个系统讲解的却很难,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出. 原理: 将一些图片在一行中平铺,然后计 ...