zoukankan      html  css  js  c++  java
  • hdu 2222 Keywords Search 夜

    http://acm.hdu.edu.cn/showproblem.php?pid=2222

    第一个AC自动机

    AC自动机就是在trie上进行kmp

    需要三个步骤

    1,建立trie

    2,求fail指针

    3,匹配

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<algorithm>
    
    #define LL long long
    
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int N=1000005;
    const int K=26;
    struct nodeTrie
    {
        nodeTrie()
        {
            v=0;
            fail=NULL;
            for(int i=0;i<K;++i)
            next[i]=NULL;
        }
        int v;
        struct nodeTrie *fail;
        struct nodeTrie *next[K];
    }*root;
    char s[N];
    void addWord(nodeTrie *p,char *s)
    {
        if(s[0]=='\0') return ;
        for(int i=0;s[i]!='\0';++i)
        {
            if(p->next[s[i]-'a']==NULL)
            p->next[s[i]-'a']=new nodeTrie;
            p=p->next[s[i]-'a'];
        }
        ++(p->v);
    }
    void init(int n)
    {
        root=new nodeTrie;
        while(n--)
        {
            gets(s);
            addWord(root,s);
        }
    }
    void bfs(nodeTrie *p)
    {
        p->fail=root;
        queue<nodeTrie *>qt;
        qt.push(p);
        while(!qt.empty())
        {
            nodeTrie *y;
            nodeTrie *x=qt.front();qt.pop();
            for(int i=0;i<K;++i)
            if(x->next[i]!=NULL)
            {
                qt.push(x->next[i]);
                if(x==root)
                {x->next[i]->fail=root;continue;}
                y=x->fail;
                while(y!=root&&y->next[i]==NULL)
                y=y->fail;
                if(y->next[i]!=NULL)
                x->next[i]->fail=y->next[i];
                else
                x->next[i]->fail=root;
            }
        }
    }
    int match(nodeTrie *p,char *s)
    {
        int wordCount=0;
        int l=0;
        while(s[l]!='\0')
        {
            while(p->next[s[l]-'a']==NULL&&p!=root)
            p=p->fail;
            if(p->next[s[l]-'a']!=NULL)
            p=p->next[s[l]-'a'];
            ++l;
            nodeTrie *fp=p;
            while(fp!=root)
            {
                if((fp->v)>0) {wordCount+=(fp->v);fp->v=0;}
                fp=fp->fail;
            }
        }
        return wordCount;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n;
            scanf("%d ",&n);
            init(n);
            bfs(root);
            gets(s);
            printf("%d\n",match(root,s));
        }
        return 0;
    }
    

      

  • 相关阅读:
    (2.3)备份与还原--事务的运行模式与处理机制
    (2.2)备份与还原--备份类型与恢复模式、备份介质
    (2.1)备份与还原--sql server文件的概念及操作
    (1.3.3)权限控制
    (1.3.2)登录验证(加密连接与登录验证)
    (1.3.1)连接安全(连接实例与网络协议及TDS端点)
    static class
    cnblog
    microsoft
    C# socket android
  • 原文地址:https://www.cnblogs.com/liulangye/p/2974881.html
Copyright © 2011-2022 走看看