zoukankan      html  css  js  c++  java
  • hdu2222-Keywords Search AC自动机

    题意:给一个字符串,和n个单词,问出现过多少个单词。

    思路:ac自动机模板题。注意每个单词只能被算一次

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std ;
    const int maxw = 26;
    const int maxn = 10005;
    const int time = 55;
    const int maxs = 1000003;
    struct DFAAC{
        int tire[maxn*time][maxw];
        int fail[maxn*time];
        int  tag[maxn*time];
        bool vis[maxn*time];
        int root ,P;
        int New(){
            tag[P] = 0;
            for(int i=0;i<maxw;i++)
                tire[P][i] = 0;
            return P++;
        }
        void Init(){
            P=0; root = New();
        }
        void Insert(char ch[]){
            int now = root;
            for(int i=0;ch[i];i++)
            {
                int &nxt = tire[now][ch[i]-'a'];
    
                if(nxt==0)
                   nxt = New();
                now = nxt;
            }
            tag[now]++;
        }
        void built(){
            queue<int>Q;
            for(int i=0;i<maxw;i++){
                int &x = tire[root][i];
                if(x!=0){
                    Q.push(x);
                    fail[x]=0;
                }
             }
             while(!Q.empty()){
                int u = Q.front();
                Q.pop();
                for(int i=0;i<maxw;i++){
                    int &v = tire[u][i];
                    if(v){
                        fail[v] = tire[fail[u]][i];
                       // tag[u] += tag[fail[u]];
                        Q.push(v);
                    }
                    else v = tire[fail[u]][i];
                }
             }
        }
        int quert(char ch[]){
            memset(vis,0,sizeof(vis));
            int ret = 0;
            int now = root;
            for(int i=0;ch[i];i++){
                 now = tire[now][ch[i]-'a'];
                 int tmp = now;
                 while(tmp!=0){
                    if(vis[tmp]) break;
                    ret += tag[tmp];
                    vis[tmp] = 1;
                    //tag[tmp] = 0;
                    tmp = fail[tmp];
                }
            }
            return ret;
        }
    };
    char ch[maxs];
    int n , t;
    DFAAC ac;
    int main()
    {
        scanf("%d",&t);
        while(t--){
           scanf("%d",&n);
            ac.Init();
           while(n--){
                scanf("%s",ch); ac.Insert(ch);
            }
            ac.built();
            scanf("%s",ch);
            printf("%d
    ",ac.quert(ch));
        }
    
    }
    View Code
  • 相关阅读:
    单元测试之NUnit一
    第一个基于ArcGIS的Android应用
    NuGet的安装和使用
    PIE调用Python获得彩色直方图
    PIE调用Python返回得到直方图矩阵数组
    PIE属性表多字段的文本绘制
    微信公众号配置和使用客服消息
    python多线程爬取斗图啦数据
    微信小微商户获取申请状态
    微信小微商户申请入驻
  • 原文地址:https://www.cnblogs.com/rtyfcvb/p/6759903.html
Copyright © 2011-2022 走看看