AcWing 142. 前缀统计(Trie)

给定N个字符串S1,S2…SNS1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1S1~SNSN中有多少个字符串是T的前缀。

输入字符串的总长度不超过106106,仅包含小写字母。

输入格式

第一行输入两个整数N,M。

接下来N行每行输入一个字符串SiSi。

接下来M行每行一个字符串T用以询问。

输出格式

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

每个答案占一行。

输入样例:

3 2

ab

bc

abc

abc

efg

输出样例:

2

0

字典树裸题。注意要更改的一点就是把insert函数里的末尾标记改为以该点为末尾的字符串的个数(即end[p]++)。Search函数里设置一个cnt变量累加待查找字符串每个节点的以其为末尾的字符串的个数,如果p==0说明剩下的部分没有在字典树里出现过了,直接return cnt即可。

#include <bits/stdc++.h>
using namespace std;
int trie[1000005][26],tot=1;
int eend[1000005]={0};
void insert(string s)
{
    int len=s.size();
    int k,p=1;
    for(k=0;k<len;k++)
    {
        int ch=s[k]-'a';
        if(trie[p][ch]==0) trie[p][ch]=++tot;
        p=trie[p][ch];
    }
    eend[p]++;
}
int search(string s)
{
    int len=s.size(),k,p=1,cnt=0;
    cnt+=eend[p];
    for(k=0;k<len;k++)
    {
        p=trie[p][s[k]-'a'];
        if(p==0) return cnt;
        cnt+=eend[p];
    }

    return cnt;
}
int main()
{
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        insert(s);
    } 
    for(i=1;i<=m;i++)
    {
        string s;
        cin>>s;
        cout<<search(s)<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lipoicyclic/p/13029123.html