zoukankan      html  css  js  c++  java
  • HDU 2222:Keywords Search(AC自动机模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=2222

    KMP是单模式串匹配的算法,而AC自动机是用于多模式串匹配的算法。主要由Trie和KMP的思想构成。

    题意:输入N个模式串,再给出一个文本串,求文本串里出现的模式串数目。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <string>
      7 #include <iostream>
      8 #include <stack>
      9 #include <map>
     10 #include <queue>
     11 using namespace std;
     12 #define N 500001
     13 /*
     14 一个模式串的某个字符匹配失败的时候,就跳到它的失败指针上继续匹配,重复上述操作,直到这个字符匹配成功,所以失败指针一定满足一个性质,它指向的一定是某个串的前缀,并且这个前缀是当前结点所在前缀的后缀,而且一定是最长后缀。
     15 */
     16 struct Ac_DFA
     17 {
     18     int next[N][26]; //一开始这里用了char结果MLE
     19     int val[N], size, root, fail[N];
     20 
     21     int creat() { //构造新节点
     22         for(int i = 0; i < 26; i++) {
     23             next[size][i] = -1;
     24         }
     25         val[size] = 0;
     26         return size++;
     27     }
     28 
     29     void init() {
     30         size = 0;
     31         root = creat();
     32     }
     33 
     34     void insert(char s[]) { //插入模式串
     35         int len = strlen(s);
     36         int now = root;
     37         for(int i = 0; i < len; i++) {
     38             int c = s[i] - 'a';
     39             if(next[now][c] == -1) {
     40                 next[now][c] = creat();
     41             }
     42             now = next[now][c];
     43         }
     44         val[now]++;
     45     }
     46 
     47     void build() { //构造fail函数
     48         queue<int> que;
     49         while(!que.empty()) que.pop();
     50         for(int i = 0; i < 26; i++) { //初始化
     51             if(next[root][i] == -1) { //如果没有边就补上去
     52                 next[root][i] = root;
     53             } else {
     54                 fail[next[root][i]] = root; //有边的话第一个结点指向root
     55                 que.push(next[root][i]);
     56             }
     57         }
     58         while(!que.empty()) {
     59             int now = que.front(); que.pop();
     60             for(int i = 0; i < 26; i++) {
     61                 if(next[now][i] == -1) {
     62                     next[now][i] = next[fail[now]][i]; //如果没有边构造一条边出来
     63                     // 构造的边是fail指针指向的节点的出边
     64                 } else {
     65                     fail[next[now][i]] = next[fail[now]][i]; //有边fail就指向与目前的相同结点(以目前匹配的串的最长后缀为前缀)的一条边
     66                     que.push(next[now][i]);
     67                 }
     68             }
     69         }
     70     }
     71 
     72     int query(char s[]) {
     73         int len = strlen(s);
     74         int ans = 0;
     75         int now = root;
     76         for(int i = 0; i < len; i++) {
     77             now = next[now][s[i] - 'a'];
     78             int tmp = now;
     79             while(tmp != root) {
     80                 ans += val[tmp];
     81                 val[tmp] = 0;
     82                 tmp = fail[tmp]; // KMP思想:当前匹配失败,沿着失配边走看有没有能够匹配的串
     83             }
     84         }
     85         return ans;
     86     }
     87 };
     88 
     89 char s[1000001];
     90 Ac_DFA ac;
     91 
     92 int main()
     93 {
     94     int t;
     95     scanf("%d", &t);
     96     while(t--) {
     97         int n;
     98         scanf("%d", &n);
     99         ac.init();
    100         for(int i = 0; i < n; i++) {
    101             scanf("%s", s);
    102             ac.insert(s);
    103         }
    104         ac.build();
    105         scanf("%s", s);
    106         int ans = ac.query(s);
    107         printf("%d
    ", ans);
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    【随笔】野生在左 科班在右——数据结构学习誓师贴
    javascript基础修炼(7)——Promise,异步,可靠性
    express中间件系统的基本实现
    javascript基础修炼(6)——前端路由的基本原理
    javascript基础修炼(5)—Event Loop(Node.js)
    一统江湖的大前端(7)React.js-从开发者到工程师
    一统江湖的大前端(6)commander.js + inquirer.js——懒,才是第一生产力
    一统江湖的大前端(5)editorconfig + eslint——你的代码里藏着你的优雅
    Jmeter接口测试之用户自定义变量(九)
    Jmeter4.0接口测试之案例实战(七)
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5995097.html
Copyright © 2011-2022 走看看