zoukankan      html  css  js  c++  java
  • hdu 3065 AC自动机 标记数组不清零

    题目链接:

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

    题目里面要我们计算每种单词出现的次数,重叠的也要计算,那么我们在查找的时候不要把标记单词结尾的数组(我这里是val)清零就可以重复计算每个单词出现的数量了。

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<cstdio>
    #include<string>
    #include<deque> 
    using namespace std;
    typedef long long LL;
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define maxn 50005
    int trie[maxn][95],fail[maxn],val[maxn],ID[maxn],num[maxn];
    int n,m,k,t,cnt;
    char s[1005][55],str[2000005];
    void init(){
        memset(trie,0,sizeof(trie));
        memset(fail,0,sizeof(fail));
        memset(val,0,sizeof(val));
        memset(num,0,sizeof(num));
        cnt=0;
    }
    void insert(char *s,int id){
        int root=0;
        for(int i=0;s[i];i++){
            int x=s[i]-32;
            if(trie[root][x]==0)
            trie[root][x]=++cnt;
            root=trie[root][x];
        }
        val[root]++;
        ID[root]=id;//记录编号 
    }
    void build_fail(){//构建fail指针 
        queue<int>q;
        int root=0;
        for(int i=0;i<95;i++){
            if(trie[root][i])
            q.push(trie[root][i]);
        }
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<95;i++){
                if(trie[u][i]){//u存在儿子i,把i的fail指向fail[u]的儿子i 
                    fail[trie[u][i]]=trie[fail[u]][i];
                    q.push(trie[u][i]);
                }else{//不存在儿子i 
                    trie[u][i]=trie[fail[u]][i];//让fail[u]的儿子i成为u的儿子 
                }
            }
        }
    }
    void query(){
        int len=strlen(str);
        int u=0;
        for(int i=0;i<len;i++){
            int id=str[i]-32;
            u=trie[u][id];
            int temp=u;
            while(temp){
                if(val[temp]){//找到一个以id+32这个字符结束的单词,我们在这里不把它的标记数组val清零 
                    num[ID[temp]]++;
                }
                temp=fail[temp];
            }
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            init();
            for(int i=1;i<=n;i++){
                scanf("%s",s[i]);
                insert(s[i],i); 
            }
            build_fail();
            scanf("%s",str);
            query();
            for(int i=1;i<=n;i++){
                if(num[i]){
                    printf("%s: ",s[i]);
                    printf("%d
    ",num[i]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    两台电脑间的消息传输
    商品库存订购管理管理程序代写代做代开发
    基于ssh的汽车配件进销存系统
    Ajax初识
    系统排队仿真源代码
    模拟一个排队系统
    Linux下,C++编程论坛题目抽取
    实践是检验真理的唯一标准2 脱壳篇03
    迪杰斯特拉算法
    最短路径求法
  • 原文地址:https://www.cnblogs.com/6262369sss/p/10301152.html
Copyright © 2011-2022 走看看