zoukankan      html  css  js  c++  java
  • 关键词匹配(Ac自动机模板题)

    2772: 关键词匹配

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 10  Solved: 4
    [Submit][Status][Web Board]

    Description

    给你N个单词,然后给定一个字符串,问一共有多少单词在这个字符串中出现过(输入相同的字符串算不同的单词,同一个单词重复出现只计一次)。

    Input

    第一行一个整数N,表示给定单词的个数。
    接下来N行,每行输入一个长度不超过50且全由小写字母组成的单词。
    最后一行输入一个长度不超过1000000的字符串。
    N≤10000

    Output

    输出一行包含一个整数,表示共在给定字符串中出现过的单词个数。

    Sample Input

    5
    she
    he
    say
    shr
    her
    yasherhs
    ​

    Sample Output

    3

    HINT

     

    Source

     题解:

      裸Ac自动机,不会的可以去看看这个博客:http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html;

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define maxn 1000005
     5 #define maxm 1000005
     6 using namespace std;
     7 int n,tot,head,tail,son[maxm][26],fai[maxm],sum[maxm],list[maxm];
     8 char s[maxn];
     9 void clear(){
    10         tot=0;
    11         memset(son,0,sizeof(son));
    12         memset(sum,0,sizeof(sum));
    13     }
    14     void insert(char *s){
    15         int p=0;
    16         for (int i=1;s[i];p=son[p][s[i]-'a'],i++) if (!son[p][s[i]-'a']) son[p][s[i]-'a']=++tot;
    17         sum[p]++;
    18     }
    19     void failed(){
    20         head=0,tail=1,list[1]=0,fai[0]=-1;
    21         while (head!=tail){
    22             int x=list[++head];
    23             for (int ch=0;ch<26;ch++)
    24                 if (son[x][ch]){
    25                     list[++tail]=son[x][ch];
    26                     int p=fai[x];
    27                     while (p!=-1&&!son[p][ch]) p=fai[p];
    28                     if (p==-1) fai[son[x][ch]]=0;
    29                     else fai[son[x][ch]]=son[p][ch];
    30                 }   
    31         }
    32     }
    33     void work(char *s){
    34         int ans=0;
    35         for (int i=1,p=0;s[i];i++){
    36             while (p&&!son[p][s[i]-'a']) p=fai[p];
    37             p=son[p][s[i]-'a'];
    38             for (int t=p;t;t=fai[t]) ans+=sum[t],sum[t]=0;
    39         }
    40         printf("%d
    ",ans);
    41     }
    42 int main()
    43 {
    44         cin>>n;//,clear();
    45         for (int i=1;i<=n;i++) scanf("%s",s+1),insert(s);
    46         failed();
    47         scanf("%s",s+1),work(s);
    48     return 0;
    49 }
    View Code
     
  • 相关阅读:
    Android 摇一摇之双甩功能
    Android 上千张图片的列表滑动加载
    Android 新手引导
    Android 自定义列表指示器
    Mininet的安装与卸载
    ubuntu装机必备
    linux系统中利用vagrant创建虚拟开发环境
    Ubuntu右键添加:open in terminal
    ryu启动问题总结
    新建WORD文档打开会出现转换文件对话框3步解决办法
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5367953.html
Copyright © 2011-2022 走看看