zoukankan      html  css  js  c++  java
  • 单词 (AC自动机)

    题目描述

    某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

    输入描述:

    第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N ≤ 200,单词长度不超过10^6

    输出描述:

    输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

    示例1

    输入

    3

    a

    aa

    aaa

    输出

    6

    3

    1

    题解

    AC自动机概念题,考的对 fail指针的理解,就是建树bfs这里就体现了AC自动机手写队列的好处,省了一次bfs

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6 + 5;
    const int M = 26;
    const int C = 'a';
    
    struct AC
    {
        int tr[maxn][M], cnt[maxn], fail[maxn], endpos[maxn]; 
        int q[maxn], tot, head, tail; 
        
        void insert(char *s, int id)
        {
            int p = 0;
            for (int i = 0; s[i]; ++i)
            {
                int ch = s[i] - C;
                if (tr[p][ch] == 0) tr[p][ch] = ++tot;
                p = tr[p][ch], ++cnt[p];
            }
            endpos[id] = p; 
        }
        
        void build()
        {
            head = 0, tail = -1;
            for (int i = 0; i < M; ++i)
                if (tr[0][i]) q[++tail] = tr[0][i];
            while (head <= tail)
            {
                int p = q[head++];
                for (int i = 0; i < M; ++i)
                    if (tr[p][i]) 
                        fail[tr[p][i]] = tr[fail[p]][i], q[++tail] = tr[p][i];
                    else tr[p][i] = tr[fail[p]][i];  
            }
        }
    }ac;
    
    int n;
    char s[maxn];
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i)
            scanf("%s", s), ac.insert(s, i);
        ac.build();
        for (int i = ac.tail; i >= 0; --i)//省去了bfs
            ac.cnt[ac.fail[ac.q[i]]] += ac.cnt[ac.q[i]];
        for (int i = 1; i <= n; ++i)
            printf("%d
    ", ac.cnt[ac.endpos[i]]);
        return 0;
    }
  • 相关阅读:
    研发环境容器化实施过程(docker + docker-compose + jenkins)
    Java虚拟机-字节码执行引擎
    Java虚拟机-类加载机制
    Java虚拟机-字节码指令
    Java虚拟机-类文件结构
    Java虚拟机理解-内存管理
    单元测试实践(SpringCloud+Junit5+Mockito+DataMocker)
    Git基础概念与Flow流程介绍
    谷歌最佳实践
    谷歌最佳实践
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12692682.html
Copyright © 2011-2022 走看看