算法模板——AC自动机
时间:2022-05-07
本文章向大家介绍算法模板——AC自动机,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实现功能——输入N,M,提供一个共计N个单词的词典,然后在最后输入的M个字符串中进行多串匹配(关于AC自动机算法,此处不再赘述,详见:Aho-Corasick 多模式匹配算法、AC自动机详解。考虑到有时候字典会相当稀疏,所以引入了chi和bro指针进行优化——其原理比较类似于邻接表,这个东西和next数组本质上是一致的,只是chi和bro用于遍历某一节点下的子节点,next用于查询某节点下是否有需要的子节点)
1 type
2 point=^node;
3 node=record
4 ex:longint;st:ansistring;
5 ct:char;
6 fat,jump,chi,bro:point;
7 next:array['A'..'Z'] of point;
8 end;
9 var
10 i,j,k,l,m,n:longint;
11 head,p:point;
12 s1,s2:ansistring;
13 function getpoint:point;inline;
14 var p:point;c1:char;
15 begin
16 new(p);
17 p^.ex:=0;p^.st:='';
18 p^.ct:=chr(0);
19 p^.bro:=nil;p^.chi:=nil;
20 p^.fat:=nil;p^.jump:=head;
21 for c1:='A' to 'Z' do p^.next[c1]:=nil;
22 exit(p);
23 end;
24 procedure ins(s1:ansistring;x:longint);inline;
25 var p:point;s2:ansistring;i:longint;
26 begin
27 p:=head;S2:='';
28 for i:=1 to length(s1) do
29 begin
30 s2:=s2+s1[i];
31 if p^.next[s1[i]]=nil then
32 begin
33 p^.next[s1[i]]:=getpoint;
34 p^.next[s1[i]]^.fat:=p;
35 p^.next[s1[i]]^.st:=s2;
36 p^.next[s1[i]]^.ct:=s1[i];
37 p^.next[s1[i]]^.bro:=p^.chi;
38 p^.chi:=p^.next[s1[i]];
39 end;
40 p:=p^.next[s1[i]];
41 end;
42 if p^.ex=0 then p^.ex:=x;
43 end;
44 procedure linkit;inline;
45 var i,j,k,l,f,r:longint;
46 d:array[0..10000] of point;
47 p,p1,p2:point;
48 begin
49 f:=1;r:=2;d[1]:=head;
50 while f<r do
51 begin
52 p:=d[f]^.chi;
53 while p<>nil do
54 begin
55 d[r]:=p;
56 if d[f]<>head then
57 begin
58 p1:=d[f]^.jump;
59 while p1<>head do
60 begin
61 if p1^.next[p^.ct]<>nil then break;
62 p1:=p1^.jump;
63 end;
64 if p1^.next[p^.ct]<>nil then p^.jump:=p1^.next[p^.ct];
65 end;
66 inc(r);
67 p:=p^.bro;
68 end;
69 inc(f);
70 end;
71 end;
72 procedure fit(s1:ansistring);inline;
73 var p,p1:point;i:longint;
74 begin
75 p:=head;
76 for i:=1 to length(s1) do
77 begin
78 if p^.next[s1[i]]=nil then
79 begin
80 while (p^.next[s1[i]]=nil) and (p<>head) do p:=p^.jump;
81 if p^.next[s1[i]]<>nil then p:=p^.next[s1[i]];
82 end
83 else p:=p^.next[s1[i]];
84 p1:=p;
85 while p1<>head do
86 begin
87 if p1^.ex<>0 then writeln('No.',p1^.ex,' ',p1^.st,' From:',i-length(p1^.st)+1);
88 p1:=p1^.jump;
89 end;
90 end;
91 end;
92 begin
93 readln(n,m);
94 head:=getpoint;head^.jump:=head;
95 for i:=1 to n do
96 begin
97 readln(s1);
98 ins(upcase(s1),i);
99 end;
100 linkit;
101 for i:=1 to m do
102 begin
103 readln(s1);
104 fit(upcase(s1));
105 end;
106 end.
107
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 华为提出十大数学挑战!解出一个就是年薪百万!
- 一道 Google 的面试题
- 生产实践 | 基于 Flink 的短视频生产消费监控
- 图数据库调研
- Swift 类构造器的使用
- 「网络IO套路」当时就靠它追到女友
- 起个简单枯燥的标题:找出连续差相同的数字
- 10分钟带你搞懂代理模式、静态代理、JDK+CGLIB动态代理
- 握草!某程序员竟然在深夜偷偷在代码里下毒!
- 自然资源部贡献的Landuse数据(2000、2010、2020)
- LoRa节点开发——SDK整体设计思路
- 01 . Nginx简介及部署
- 02 . Nginx平滑升级和虚拟主机
- LoRa节点开发——LoRaWAN节点入网代码详解
- 03 . Nginx日志配置及日志切割