实现功能——输入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:=;p^.st:='';
  18. p^.ct:=chr();
  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:= 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= then p^.ex:=x;
  43. end;
  44. procedure linkit;inline;
  45. var i,j,k,l,f,r:longint;
  46. d:array[..] of point;
  47. p,p1,p2:point;
  48. begin
  49. f:=;r:=;d[]:=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:= 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<> then writeln('No.',p1^.ex,' ',p1^.st,' From:',i-length(p1^.st)+);
  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:= to n do
  96. begin
  97. readln(s1);
  98. ins(upcase(s1),i);
  99. end;
  100. linkit;
  101. for i:= to m do
  102. begin
  103. readln(s1);
  104. fit(upcase(s1));
  105. end;
  106. end.

算法模板——AC自动机的更多相关文章

  1. [算法模版]AC自动机

    [算法模版]AC自动机 基础内容 板子不再赘述,OI-WIKI有详细讲解. \(query\)函数则是遍历文本串的所有位置,在文本串的每个位置都沿着\(fail\)跳到根,将沿途所有元素答案++.意义 ...

  2. 算法竞赛模板 AC自动机

    AC自动机基本操作 (1) 在AC自动机中,我们首先将每一个模式串插入到Trie树中去,建立一棵Trie树,然后构建fail指针. (2) fail指针,是穿插在Trie树中各个结点之间的指针,顾名思 ...

  3. 【字符串算法】AC自动机

    国庆后面两天划水,甚至想接着发出咕咕咕的叫声.咳咳咳,这些都不重要!最近学习了一下AC自动机,发现其实远没有想象中的那么难. AC自动机的来历 我知道,很多人在第一次看到这个东西的时侯是非常兴奋的.( ...

  4. luoguP3808[模板]AC自动机(简单版)

    传送门 ac自动机模板题,裸的多串匹配 代码: #include<cstdio> #include<iostream> #include<algorithm> #i ...

  5. luoguP3796[模板]AC自动机(加强版)

    传送门 ac自动机模板,可能我写的ac自动机是有点问题的,所以跑的有些慢 暴力跳fail统计 代码: #include<cstdio> #include<iostream> # ...

  6. 模板 AC自动机

    题目描述 有$N$ 个由小写字母组成的模式串以及一个文本串$T$ .每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串$T$ 中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据 ...

  7. 洛谷.3808/3796.[模板]AC自动机

    题目链接:简单版,增强版 简单版: #include <cstdio> #include <cstring> const int N=1e6+5,S=26; char s[N] ...

  8. 模板—AC自动机

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; struct ...

  9. 模板——AC自动机

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

随机推荐

  1. LINQ to Sql系列一 增,删,改

    首先,我们来了解一下LINQ to sql 是什么,我想从以下几点来做说明. 1,LINQ是从.net framework 3.0开始引入的的语言特性,主要是用来对集合数据进行操作的.2,LINQ t ...

  2. PHP中目录解析函数

    dirname(string path):给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名. 斜线(/)和反斜线(\)都可以用作目录分隔符.在其它环境下是斜线(/). dir ...

  3. java算法 蓝桥杯 格子位置

    问题描述 输入三个自然数N,i,j (1<=i<=N,1<=j<=N),输出在一个N*N格的棋盘中,与格子(i,j)同行.同列.同一对角线的所有格子的位置. 输入格式 输入共三 ...

  4. Java错题

    加粗为正确答案,绿色为错选答案 1.对于以下代码: for ( int i=0; i<10; i++)  System.out.println(i); for循环后,i的值是多少? A.i不再存 ...

  5. html 一般标签 常用标签 表格

    body的属性: bgcolor                页面背景色 background            背景壁纸.图片 text                    文字颜色 top ...

  6. 蓝桥网试题 java 入门训练 A+B问题

    ---------------------------------------------------------------------------------------------------- ...

  7. HDU 2080 夹角有多大II

    夹角有多大II Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. DB2_自动生成值

    生成数字序列的两种方法 在 DB2 中可以用两种方法自动生成一个数字序列: 定义带有 IDENTITY 属性的列. 创建 SEQUENCE 对象. IDENTITY 列 当用 IDENTITY 属性定 ...

  9. docker - 容器里安装ssh

    docker安装ssh 通过命令行安装 pull ubuntu镜像 docker pull ubuntu:latest 启动并进入bash docker run -it -d ubuntu:laste ...

  10. 原生js实现轮播图

    原生js实现轮播图 很多网站上都有轮播图,但找到一个系统讲解的却很难,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出. 原理: 将一些图片在一行中平铺,然后计 ...