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

    题目:

    小张最近在忙毕设,所以一直在读论文。一篇论文是由许多单词组成的。

    但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。

    输入

    第一行一个整数N,表示有N个单词。接下来N行每行一个单词,每个单词都由小写字母('a'-'z')组成。(N≤200, 单词总长度不超过106)

    输出

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

    样例输入

    3
    a
    aa
    aaa

    样例输出

    6
    3
    1

    提示

    可以将论文内容看做'a aa aaa'。

    题解:可以用AC自动机来解,插入单词的时候,在每个字母位置计数器加1,统计每个单词结尾的计数器即可。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    #define N 250
    #define maxn 1000100
    struct TNode
    {
        TNode *fail;
        TNode *next[26];
        int cnt;
        TNode()
        {
            cnt = 0;
            for(int i = 0; i < 26; i++)
                next[i] = NULL;
            fail = NULL;
            return;
        }
    };
    
    TNode *root;
    int Tcnt;
    TNode *TQ[N];
    void Insert(const char *s)
    {
        int len = strlen(s);
        TNode *p = root;
        for(int i = 0; i < len; i++)
        {
            if(p->next[s[i]-'a'] == NULL)
                p->next[s[i]-'a'] = new TNode();
            p = p->next[s[i]-'a'];
            p->cnt++;
        }
        TQ[Tcnt++] = p;
        return ;
    }
    
    TNode *queue[maxn];
    
    void build_ac_automation()
    {
        int front, rear;
        front = rear = 0;
        root -> fail = root;
        for(int i = 0; i < 26; i++)
        {
            if(root->next[i] != NULL)
            {
                root ->next[i]->fail = root;
                queue[rear++] = root->next[i];
            }
        }
    
        while(front < rear)
        {
            TNode *p = queue[front++];
            for(int i = 0; i < 26; i++)
            {
                TNode *q = p->fail;
                if(p->next[i] == NULL) continue;
                queue[rear++] = p->next[i];
                while(q->next[i] == NULL && q!=root)
                    q = q->fail;
                if(q->next[i] == NULL)
                    p->next[i]->fail = root;
                else p->next[i]->fail = q->next[i];
            }
        }
        while(rear>0){
            --rear;
            queue[rear]->fail->cnt += queue[rear]->cnt;
        }
        return ;
    }
    
    char s[1000010];
    
    int main()
    {
        int T,n;
        while(~scanf("%d", &n))
        {
            Tcnt = 0;
            root = new TNode();
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
            {
                scanf("%s", s);
                Insert(s);
            }
            build_ac_automation();
            for(int i = 0; i < n; i++)
                printf("%d
    ", TQ[i]->cnt);
    
        }
        return 0;
    }
  • 相关阅读:
    Java构造方法之间的调用
    JavaNote
    微信小程序-智能机器人
    微信小程序-今日头条案例
    微信小程序-记账本
    51job爬虫
    Xcode文件目录选中变成白色, 解决方案
    Mac通过以太网共享网络
    Mac系统Safari浏览器启动无图模式
    iOS9.0之后不支持http请求解决方案
  • 原文地址:https://www.cnblogs.com/beisong/p/4497741.html
Copyright © 2011-2022 走看看