zoukankan      html  css  js  c++  java
  • AC自动机

    题目要求:输入n个单词,然后输入一段字符串,请问字符串中第几个位置第一次出现了该单词。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    using namespace std;
    char str[1010][100];
    int ans;
    struct Trie
    {
        int next[1010*50][258],fail[1010*50],end[1010*50];
        int root,L;
        int newnode()
        {
            for(int i = 0;i < 258;i++)
                next[L][i] = -1;
            end[L++] = -1;
            return L-1;
        }
        void init()
        {
            L = 0;
            root = newnode();
        }
        void insert(char s[],int id)
        {
            int len = strlen(s);
            int now = root;
            for(int i = 0;i < len;i++)
            {
                if(next[now][s[i]] == -1)
                    next[now][s[i]] = newnode();
                now = next[now][s[i]];
            }
            end[now] = id;
        }
       void build()
        {
            queue<int>Q;
            fail[root] = root;
            for(int i = 0;i < 128;i++)
                if(next[root][i] == -1)
                    next[root][i] = root;
                else
                {
                    fail[next[root][i]] = root;
                    Q.push(next[root][i]);
                }
            while(!Q.empty())
            {
                int now = Q.front();
                Q.pop();
                for(int i = 0;i < 258;i++)
                    if(next[now][i] == -1)
                        next[now][i]=next[fail[now]][i];
                    else
                    {
                        fail[next[now][i]]=next[fail[now]][i];
                        Q.push(next[now][i]);
                    }
            }
        }
        int num[1010];
        void query(char buf[],int n)
        {
            int count=0;
            for(int i = 0;i < n;i++)
                num[i] = 0;
            int len=strlen(buf);
            int now=root;
            for(int i=0;i<len;i++)
            {
                if(buf[i]==' ')
                    count++;
                now=next[now][buf[i]];
                int temp = now;
                while( temp != root )
                {
                    if(end[temp] != -1&&num[end[temp]]==0)
                        num[end[temp]]=count;
                    temp = fail[temp];
                }
            }
           for(int i = 0;i < n;i++)
                if(num[i] > 0)
                    printf("%s: %d
    ",str[i],num[i]);
        }
    
    };
    
    char buf[2000010];
    Trie ac;
    int main()
    {
        int n;
        while(scanf("%d",&n) == 1)
        {
            ans=0;
            ac.init();
             getchar();
            for(int i=0;i<n;i++)
            {
                gets(str[i]);
                ac.insert(str[i],i);
            }
            ac.build();
            gets(buf);
            ac.query(buf,n);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Redis学习手册(Set数据类型)
    Redis学习手册(Key操作命令)
    Redis学习手册(String数据类型)
    Redis学习手册(开篇)
    SQLite学习手册(目录)
    Redis学习手册(Hashes数据类型)
    Redis学习手册(SortedSets数据类型)
    Redis学习手册(List数据类型)
    加密,解密
    异步 '省','市','区' 三级连动
  • 原文地址:https://www.cnblogs.com/NaCl/p/9580096.html
Copyright © 2011-2022 走看看