zoukankan      html  css  js  c++  java
  • 字符串:AC自动机

    给出一个字典和一个模式串,问模式串中出现几个字典中的单词

    最后一行是大串,之前输入的是小串

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 char s[51],m[1000001];
     5 int T,n,sz,ans;
     6 int a[500001][27],q[500001],point[500001],danger[500001];
     7 bool mark[500001];
     8 void ins()
     9 {
    10     int now=1,l=strlen(s);
    11     for(int i=0;i<l;i++)
    12     {
    13         int t=s[i]-'a'+1;
    14         if(a[now][t])now=a[now][t];
    15         else now=a[now][t]=++sz;
    16     }
    17     danger[now]++;
    18 }
    19 void acmach()
    20 {
    21     int t=0,w=1,now;
    22     q[0]=1;point[1]=0;
    23     while(t<w)
    24     {
    25         now=q[t++];
    26         for(int i=1;i<=26;i++)
    27         {
    28             if(!a[now][i])continue;
    29             int k=point[now];
    30             while(!a[k][i])k=point[k];
    31             point[a[now][i]]=a[k][i];
    32             q[w++]=a[now][i];
    33         }
    34     }
    35 }
    36 void solve()
    37 {
    38     int k=1,l=strlen(m);
    39     for(int i=0;i<l;i++)
    40     {
    41         mark[k]=1;
    42         int t=m[i]-'a'+1;
    43         while(!a[k][t])k=point[k];
    44         k=a[k][t];
    45         if(!mark[k])
    46             for(int j=k;j;j=point[j])
    47             {
    48                 ans+=danger[j];
    49                 danger[j]=0;
    50             }
    51     }
    52     printf("%d
    ",ans);
    53 }
    54 int main()
    55 {
    56     scanf("%d",&T);
    57     while(T--)
    58     {
    59         sz=1;ans=0;
    60         scanf("%d",&n);
    61         for(int i=1;i<=26;i++)a[0][i]=1;
    62         while(n--)
    63         {
    64             scanf("%s",s);
    65             ins();
    66         }
    67         acmach();
    68         scanf("%s",m);
    69         solve();
    70         for(int i=1;i<=sz;i++)
    71         {
    72             point[i]=danger[i]=mark[i]=0;
    73             for(int j=1;j<=26;j++)
    74                 a[i][j]=0;
    75           }
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    用户场景描述
    构建之法阅读笔记03
    冲刺记录(4.26)
    力扣-dp基础问题思维构建
    力扣-二叉树专题
    力扣-巧妙哈希
    力扣-双指针问题
    力扣-区间问题
    力扣-单调栈与单调队列问题
    力扣-股票买卖专题
  • 原文地址:https://www.cnblogs.com/aininot260/p/9643632.html
Copyright © 2011-2022 走看看