• HDU 2222 Keywords Search AC自动机


    题意:给你n个模式串,问一共有多少个模式串在文本串中出现过

    解题思路:对于多模式,单文本串的题目显然是要用 AC自动机来解决的,多文本串,单模式串,显然是要用KMP求解的,这也是KMP 和 AC自动机同为字符串匹配的不同之处。

    解题代码:

      1 // File Name: temp.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年09月11日 星期四 15时18分26秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #include<queue>
     25 #define LL long long
     26 #define maxn 500010
     27 using namespace std;
     28 struct Trie
     29 {
     30    int next[maxn][26],fail[maxn],end[maxn];
     31    int root, L;
     32    int newnode()
     33    {
     34        for(int i = 0 ;i < 26;i ++)
     35           next[L][i] = -1;
     36        end[L++] = 0 ;
     37        return L-1;
     38    }
     39    int init()
     40    {
     41       int L = 0 ; 
     42       root = newnode();
     43    }
     44    int insert(char buf[])
     45    {
     46       int len = strlen(buf);
     47       int now = root;
     48       for(int i = 0 ;i < len ;i ++)
     49       {
     50          if(next[now][buf[i] - 'a'] ==  -1)
     51          {
     52              next[now][buf[i] - 'a'] = newnode();
     53          }
     54          now = next[now][buf[i]-'a'];
     55       }
     56       end[now]++;
     57    }
     58    void build()
     59    {
     60        queue<int> Q; 
     61        //这里为何要用优先队列来解决这个问题,主要原因是fail指针是按层数来的。
     62        fail[root] = root; 
     63        for(int i = 0;i < 26;i ++)
     64        {
     65             if(next[root][i] == -1)
     66             {
     67                next[root][i] = root;  //指向root 是没有问题的,我们主要是通过end 数组对个数进行计数的。    
     68             }else{
     69                fail[next[root][i]] = root;
     70                Q.push(next[root][i]);
     71             }
     72        }
     73        while(!Q.empty())
     74        {
     75           int now = Q.front();
     76           Q.pop();
     77           for(int i = 0 ;i < 26;i ++)
     78           {
     79              if(next[now][i] == -1)
     80                  next[now][i] =  next[fail[now]][i]; 
     81              else{
     82                 fail[next[now][i]] = next[fail[now]][i];
     83                 Q.push(next[now][i]);
     84              }
     85           }
     86        }
     87    }
     88    int query(char buf[])
     89    {
     90       int len = strlen(buf);
     91       int now = root ; 
     92       int res = 0 ; 
     93       for(int i = 0 ;i < len;i ++)
     94       {
     95         now = next[now][buf[i] -'a'];
     96         int temp = now ; 
     97         while(temp != root)
     98         {
     99            res += end[temp];
    100            end[temp] = 0 ; 
    101            temp = fail[temp];//  不断的寻找 fail 指针 因为会出线这样的字符串  abcd bcd cd
    102         }
    103       }
    104       return res;
    105    }
    106 };
    107 char buf[1000010];
    108 Trie ac;
    109 int main(){
    110     int T;
    111     int n;
    112     scanf("%d",&T);
    113     {
    114       while(T--)
    115       {
    116          scanf("%d",&n);
    117          ac.init();
    118          for(int i = 0 ;i < n;i ++)
    119          {
    120             scanf("%s",buf);
    121             ac.insert(buf);
    122          }
    123          ac.build();
    124          scanf("%s",buf);
    125          printf("%d
    ",ac.query(buf));
    126       }
    127     }
    128 return 0;
    129 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    virtualenv与virtualenvwrapper
    数据类型、变量定义、数据类型转换
    计算机存储单元、标识符
    html单页面中用angular js
    svn客户端访问失败,错误“请求的名称有效,但是找不到请求的类型”的解决
    php 获取某数组中出现次数最多的值(重复最多的值)与出现的次数
    数据库导入时出现“2006
    phpstorm 激活
    取消本地SVN文件夹与服务器的关联
    js实现倒计时函数
  • 原文地址:https://www.cnblogs.com/zyue/p/3966726.html
Copyright © 2020-2023  润新知