zoukankan      html  css  js  c++  java
  • 前缀统计 [Trie]

    前缀统计

    描述

    给定N个字符串S1,S2...SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。输入字符串的总长度不超过10^6,仅包含小写字母。

    输入格式

    第一行两个整数N,M。接下来N行每行一个字符串Si。接下来M行每行一个字符串表示询问。

    输出格式

    对于每个询问,输出一个整数表示答案

    样例输入

    3 2
    ab
    bc
    abc
    abc
    efg

    样例输出

    2
    0

    题解

    trie树操作,把这n个字符串插入到trie中,并更新一下节点信息
    在这道题中,每个节点只需要保存cnt表示当前节点是多少个字符串的末尾节点,那么如果被询问的字符串T匹配到当前节点,表示从T的首字符开始到当前一直是匹配的,那么我们在查询过程中累加节点的cnt值就可以了
    中间注意判断一下,如果trie已经搜到了叶子节点还要但匹配还没有完成,直接return ans

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define Min(a,b) (a)<(b)?(a):(b)
    #define Max(a,b) (a)>(b)?(a):(b)
    #define in(i) (i=read())
    using namespace std;
    int read() {
        int ans=0,f=1; char i=getchar();
        while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
        while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
        return ans*f;
    }
    int n,m,tot;
    int trie[1000010][27],cnt[1000010];
    void insert(char* str) {
        int len=strlen(str),p=0;
        for(int i=0;i<len;i++) {
            int ch=str[i]-'a';
            if(!trie[p][ch]) trie[p][ch]=++tot;
            p=trie[p][ch];
        }
        cnt[p]++;
    }
    int search(char* str) {
        int ans=0;
        int len=strlen(str),p=0;
        for(int i=0;i<len;i++) {
            int ch=str[i]-'a';
            p=trie[p][ch];
            if(!p) return ans;
            ans+=cnt[p];
        }
        return ans;
    }
    int main()
    {
        char s[1000010];
        in(n); in(m);
        for(int i=1;i<=n;i++) {
            scanf("%s",s); insert(s);
        }
        for(int i=1;i<=m;i++) {
            scanf("%s",s);
            printf("%d
    ",search(s));
        }
        return 0;
    }
    

    博主蒟蒻,随意转载.但必须附上原文链接

    http://www.cnblogs.com/real-l/

  • 相关阅读:
    IT教育课程考评系统开发-07
    2020091201-1
    ip
    输入框枚举
    语言枚举
    《岁月神偷》弹唱和弦吉他谱_六线谱
    string 转化成 string数组
    获取类的字段值
    获取类的字段
    最全的省份递归
  • 原文地址:https://www.cnblogs.com/real-l/p/9368068.html
Copyright © 2011-2022 走看看