1. // 求目标串中出现了几个模式串
  2. //====================
  3. #include <stdio.h>
  4. #include <algorithm>
  5. #include <iostream>
  6. #include <string.h>
  7. #include <queue>
  8. using namespace std;
  9.  
  10. struct Trie
  11. {
  12. int next[][],fail[],end[];
  13. int root,L;
  14. int newnode()
  15. {
  16. for(int i = ;i < ;i++)
  17. next[L][i] = -;
  18. end[L++] = ;
  19. return L-;
  20. }
  21. void init()
  22. {
  23. L = ;
  24. root = newnode();
  25. }
  26. void insert(char buf[])
  27. {
  28. int len = strlen(buf);
  29. int now = root;
  30. for(int i = ;i < len;i++)
  31. {
  32. if(next[now][buf[i]-'a'] == -)
  33. next[now][buf[i]-'a'] = newnode();
  34. now = next[now][buf[i]-'a'];
  35. }
  36. end[now]++;
  37. }
  38. void build()
  39. {
  40. queue<int>Q;
  41. fail[root] = root;
  42. for(int i = ;i < ;i++)
  43. if(next[root][i] == -)
  44. next[root][i] = root;
  45. else
  46. {
  47. fail[next[root][i]] = root;
  48. Q.push(next[root][i]);
  49. }
  50. while( !Q.empty() )
  51. {
  52. int now = Q.front();
  53. Q.pop();
  54. for(int i = ;i < ;i++)
  55. if(next[now][i] == -)
  56. next[now][i] = next[fail[now]][i];
  57. else
  58. {
  59. fail[next[now][i]]=next[fail[now]][i];
  60. Q.push(next[now][i]);
  61. }
  62. }
  63. }
  64. int query(char buf[])
  65. {
  66. int len = strlen(buf);
  67. int now = root;
  68. int res = ;
  69. for(int i = ;i < len;i++)
  70. {
  71. now = next[now][buf[i]-'a'];
  72. int temp = now;
  73. while( temp != root )
  74. {
  75. res += end[temp];
  76. end[temp] = ;
  77. temp = fail[temp];
  78. }
  79. }
  80. return res;
  81. }
  82. void debug()
  83. {
  84. for(int i = ;i < L;i++)
  85. {
  86. printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
  87. for(int j = ;j < ;j++)
  88. printf("%2d",next[i][j]);
  89. printf("]\n");
  90. }
  91. }
  92. };
  93. char buf[];
  94. Trie ac;
  95. int main()
  96. {
  97. int T;
  98. int n;
  99. scanf("%d",&T);
  100. while( T-- )
  101. {
  102. scanf("%d",&n);
  103. ac.init();
  104. for(int i = ;i < n;i++)
  105. {
  106. scanf("%s",buf);
  107. ac.insert(buf);
  108. }
  109. ac.build();
  110. scanf("%s",buf);
  111. printf("%d\n",ac.query(buf));
  112. }
  113. return ;
  114. }
  1. //输出每个模式串出现的次数
  2.  
  3. #include <iostream>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <algorithm>
  7. #include <queue>
  8. using namespace std;
  9.  
  10. char str[][];
  11. struct Trie
  12. {
  13. int next[*][],fail[*],end[*];
  14. int root,L;
  15. int newnode()
  16. {
  17. for(int i = ;i < ;i++)
  18. next[L][i] = -;
  19. end[L++] = -;
  20. return L-;
  21. }
  22. void init()
  23. {
  24. L = ;
  25. root = newnode();
  26. }
  27. void insert(char s[],int id)
  28. {
  29. int len = strlen(s);
  30. int now = root;
  31. for(int i = ;i < len;i++)
  32. {
  33. if(next[now][s[i]] == -)
  34. next[now][s[i]] = newnode();
  35. now = next[now][s[i]];
  36. }
  37. end[now] = id;
  38. }
  39. void build()
  40. {
  41. queue<int>Q;
  42. fail[root] = root;
  43. for(int i = ;i < ;i++)
  44. if(next[root][i] == -)
  45. next[root][i] = root;
  46. else
  47. {
  48. fail[next[root][i]] = root;
  49. Q.push(next[root][i]);
  50. }
  51. while(!Q.empty())
  52. {
  53. int now = Q.front();
  54. Q.pop();
  55. for(int i = ;i < ;i++)
  56. if(next[now][i] == -)
  57. next[now][i]=next[fail[now]][i];
  58. else
  59. {
  60. fail[next[now][i]]=next[fail[now]][i];
  61. Q.push(next[now][i]);
  62. }
  63. }
  64. }
  65. int num[];
  66. void query(char buf[],int n)
  67. {
  68. for(int i = ;i < n;i++)
  69. num[i] = ;
  70. int len=strlen(buf);
  71. int now=root;
  72. for(int i=;i<len;i++)
  73. {
  74. now=next[now][buf[i]];
  75. int temp = now;
  76. while( temp != root )
  77. {
  78. if(end[temp] != -)
  79. num[end[temp]]++;
  80. temp = fail[temp];
  81. }
  82. }
  83. for(int i = ;i < n;i++)
  84. if(num[i] > )
  85. printf("%s: %d\n",str[i],num[i]);
  86. }
  87.  
  88. };
  89.  
  90. char buf[];
  91. Trie ac;
  92. void debug()
  93. {
  94. for (int i = ; i < ac.L; i++)
  95. {
  96. printf("id = %3d ,fail = %3d ,end = %3d, chi = [",i,ac.fail[i],ac.end[i]);
  97. for (int j = ; j < ; j++)
  98. printf("%2d ",ac.next[i][j]);
  99. printf("]\n");
  100. }
  101. }
  102. int main()
  103. {
  104. // freopen("in.txt","r",stdin);
  105. // freopen("out.txt","w",stdout);
  106. int n;
  107. while(scanf("%d",&n) == )
  108. {
  109. ac.init();
  110. for(int i = ;i < n;i++)
  111. {
  112. scanf("%s",str[i]);
  113. ac.insert(str[i],i);
  114. }
  115. ac.build();
  116. scanf("%s",buf);
  117. ac.query(buf,n);
  118. }
  119. return ;
  120. }

转自bin神 orz

AC自动机 专题的更多相关文章

  1. AC自动机专题

    AC自动机简介:KMP是用于解决单模式串匹配问题, AC自动机用于解决多模式串匹配问题. 精华:设这个节点上的字母为C,沿着他父亲的失败指针走,直到走到一个节点,他的儿子中也有字母为C的节点.然后把当 ...

  2. AC自动机专题总结

    最近学习了AC自动机,做了notonlysuccess大牛里面的题,也该来个总结了. AC自动机(Aho-Corasick Automaton)在1975年产生于贝尔实验室,是著名的多模匹配算法之一. ...

  3. 【原创】AC自动机小结

    有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配.           AC自动机 其实 就是创建了一个状态的转移图,思想很 ...

  4. AC自动机(AC automation)

    字典树+KMP 参考自: http://www.cppblog.com/mythit/archive/2009/04/21/80633.html ; //字典大小 //定义结点 struct node ...

  5. 转自kuangbin的AC自动机(赛前最后一博)

    有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配.           AC自动机 其实 就是创建了一个状态的转移图,思想很 ...

  6. HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)

    最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...

  7. 「kuangbin带你飞」专题十七 AC自动机

    layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...

  8. [专题总结]AC自动机

    其实前面的模板也不是1A,我在题库里提前做过,也不必在意罚时,刚开始我在做别的专题 裸模板我就不说了,各个博客讲解的很明白 void insert(string s){ ,len=s.size(); ...

  9. [专题汇总]AC自动机

    1.The 2011 ACM-ICPC Asia Dalian Regional Contest ZOJ 3545 Rescue the Rabbit  简单的AC自动机+状压DP, 状态DP[nod ...

随机推荐

  1. uva 10491

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. [Js]JavaScript闭包和范围的快速测试

    1. if (!("a" in window)) { var a = 1; } alert(a); [分析]代码含义:如果window不包含属性a,就声明一个变量a并赋值为1 ①J ...

  3. 戴文的Linux内核专题:03驱动程序

    转自Linux中国 驱动程序是使内核能够沟通和操作硬件或协议(规则和标准)的小程序.没有驱动程序,内核不知道如何与硬件沟通或者处理协议(内核实际上先发送指令给BIOS,然后BIOS传给硬件). Lin ...

  4. get( )与getline( )区别

    get与getline区别不是很大,但一个明显的区别是get遇到 '\n '字符后便返回,这是 '\n '还在缓冲区中,所以下次读出来的将是 '\n ',而getline遇到 '\n '也返回,但它会 ...

  5. android 回调函数

    http://blog.csdn.net/xiaanming/article/details/8703708 此为回调的java 实例 http://www.cnblogs.com/qingchen1 ...

  6. Cannot change network to bridged: There are no un-bridged host network adapters解决方法

    首先,在你安装上了虚拟机后要确保你也安装了桥接的协议,这可以通过点击右键“网上邻居”,在其中可以看到有两个虚拟出来的网络一个VMnet1,另一个是VMnet8, 如下图所示. 如果没有安装,可以通过下 ...

  7. 2799元的HTC One时尚版要卖疯了

    俗话说“好人有好报”,这句话同样可以应用到手机上.本月初,HTC正式公布了HTC One时尚版的售价,裸机2799元,礼包价2999元(配智能立显保护套).该价格一出,立刻引来一片哗然.因为大家都不相 ...

  8. PHPSESSID的cookie

    如果PHP脚本中有: 1 session_start(); 则说明使用了SESSION. SESSION是一种机制,可以在服务器端跨文件暂时保存数据或传递数据,常用于购物车等方面. SESSION只在 ...

  9. C# 使用命令行编译单个CS文件

    编译单个CS文件. 1.编译   File.cs   以产生   File.exe:       csc   File.cs     2.编译   File.cs   以产生   File.dll:  ...

  10. python03函数、递归

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 1.函数基本语法及特性 函数是什么? 函数一词来源于数学 ...