zoukankan      html  css  js  c++  java
  • AC自动机(Keywords Search)

    题目链接:https://cn.vjudge.net/contest/280743#problem/A

    题目大意:首先给你T组测试样例,然后给你n个字符串,最后再给你一个模式串,然后问你这一些字符串中是模式串的子串的有多少个?

    具体思路:AC自动机模板题,先说一下各个数组的作用吧,ch数组是字典树中的数组,val也是字典树中的数组,储存的是从根节点到当前这个节点是不是有字符串。fail和last就是AC自动机中的数组了,fail数组的作用就是从根节点到当的节点形成的字符串的后缀是一个新的路径的前缀,能够在匹配失败的时候,通过指针的跳动来节省时间。last数组的作用就是在求和的时候方便记录,如果当前节点有字符串的话,直接通过指针的跳动能够避免当前节点没有字符串的情况。

    AC代码:

      1 #include<iostream>
      2 #include<stack>
      3 #include<stdio.h>
      4 #include<cstring>
      5 #include<string>
      6 #include<cmath>
      7 #include<queue>
      8 #include<algorithm>
      9 using namespace std;
     10 # define ll long long
     11 const int maxn = 2e5+50000;
     12 const int maxm = 1e6+100;
     13 char str[maxm];
     14 int tot,ch[maxn][30],val[maxn];
     15 int fail[maxn],last[maxn];
     16 void add()
     17 {
     18     int p=0;
     19     int len=strlen(str);
     20     for(int i=0; i<len; i++)
     21     {
     22         int u=str[i]-'a';
     23         if(!ch[p][u])
     24             ch[p][u]=++tot;
     25         p=ch[p][u];
     26     }
     27     val[p]++;
     28 }
     29 void getfail()
     30 {
     31     queue<int>q;
     32     for(int i=0; i<26; i++)
     33     {
     34         if(ch[0][i])
     35             q.push(ch[0][i]);
     36     }
     37     while(!q.empty())
     38     {
     39         int top=q.front();
     40         q.pop();
     41         for(int i=0; i<26; i++)
     42         {
     43             int u=ch[top][i];
     44             if(u==0)
     45                 continue;
     46                 q.push(u);
     47             int v=fail[top];
     48             while(v&&ch[v][i]==0)
     49                 v=fail[v];
     50             fail[u]=ch[v][i];
     51             last[u]=val[fail[u]] ? fail[u] : last[fail[u]];
     52         }
     53     }
     54 }
     55 int cal(int t)
     56 {
     57     int ans=0;
     58     while(t)
     59     {
     60         ans+=val[t];
     61          val[t]=0;
     62         t=last[t];
     63     }
     64     return ans;
     65 }
     66 int getans()
     67 {
     68     int ans=0;
     69     int len=strlen(str);
     70     int p=0;
     71     for(int i=0; i<len; i++)
     72     {
     73       int u=str[i]-'a';
     74         while(p&&ch[p][u]==0)
     75             p=fail[p];
     76             p=ch[p][u];
     77         if(val[p])
     78             ans+=cal(p);
     79         else if(fail[p])
     80             ans+=cal(fail[p]);
     81     }
     82     return ans;
     83 }
     84 void init()
     85 {
     86     for(int i=0; i<tot; i++)
     87     {
     88         fail[i]=0,last[i]=0,val[i]=0;
     89         for(int j=0; j<30; j++)
     90         {
     91             ch[i][j]=0;
     92         }
     93     }
     94     tot=0;
     95 }
     96 int main()
     97 {
     98     int T;
     99     scanf("%d",&T);
    100     while(T--)
    101     {
    102         init();
    103         int n;
    104         scanf("%d",&n);
    105         for(int i=1; i<=n; i++)
    106         {
    107             scanf("%s",str);
    108             add();
    109         }
    110         getfail();
    111         scanf("%s",str);
    112         int ans=getans();
    113         printf("%d
    ",ans);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    xshell的安装及连接linux的使用方法
    linux中yum install 命令无效
    linux-centOS环境下安装jdk8
    centOS不显示ipv4地址的解决办法
    centOS开启和关闭防火墙
    java-分布式-索引
    java-网络通信-索引
    java-中间件
    java-框架-索引
    JVM-索引
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10309605.html
Copyright © 2011-2022 走看看