算法模板——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 ...
随机推荐
- 部署Sharding分片
这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群. MongoDB 的数据分块称为 ch ...
- node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource7 本博客同步在https://cnodejs.o ...
- 开箱即用 - Grunt合并和压缩 js,css 文件
js,css 文件合并与压缩 Grunt 是前端自动化构建工具,类似webpack. 它究竟有多强悍,请看它的 介绍. 这里只演示如何用它的皮毛功能:文件合并与压缩. 首先说下js,css 合并与压缩 ...
- HDU 4570(区间dp)
E - Multi-bit Trie Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- windows环境下使用git客户端、github和tortoisegit管理项目代码
一.为什么 为什么不用svn? svn是一个优秀的代码和版本管理工具,使用svn只需要搭建好svn中央仓库,配置本地svn客户端即可,自从google code关闭服务之后,互联网上已经没有非常好的公 ...
- js事件对象
哎,事件也有对象呦.程序员一直在讲对象对象,那么,过年是不是该带个对象回家呢?好了,既然事件有对象,承认这个事实吧!哈哈,那么,其就有属性,接下来,就放个 例子来讲讲,顺便把常用的属性也添加进去.. ...
- asp.net core mvc剖析:启动流程
asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...
- 读书笔记 effective c++ Item 8 不要让异常(exceptions)离开析构函数
1.为什么c++不喜欢析构函数抛出异常 C++并没有禁止析构函数出现异常,但是它肯定不鼓励这么做.这是有原因的,考虑下面的代码: class Widget { public: ... ~Widget( ...
- JS冒号的作用
JS中冒号的作用1.声明对象的成员2.switch语句分支3.三元表达式 1.声明对象的成员 var Book = { Name: '法', Price: 100, Discount : functi ...
- 由merge into引起的序列跳号
最近生产库反应出一个问题,某张表的主键ID并没有按照原计划的期望增加,而是间歇性跳号,每次跳2万多,经过研究发现是某个同步过程的merge into引起的,具体语句如下 merge into t_if ...