给出很多的串,然后有很多的询问,每次询问需要回答,以这个串为前缀的单词有几个。
把单词建立成字典树,插入的单词的时候,统计每个字符节点经过几次,然后询问的时候,直接查询,没有这个前缀就是0,否则就是f[now]即可
空间的取值,假设n个串,每个长度不大于x,最坏的情况也就是n*x个空间就够了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#include<vector>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define LL long long
#define pb push_back
#define gcd __gcd
#define For(i,j,k) for(int i=(j);i<k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)
const int maxn = 1e6+10;
const int inf = 1 << 28;
struct Trie{
int child[maxn][30];
int f[maxn];
int root,L;
int newNode(){
cl(child[L],-1);
f[L]=0;
return L++;
}
void init(){
L = 0;
root = newNode();
}
void insert(const char *s){
int now = root;
int len = strlen(s);
for(int i=0;i<len;i++){
if(child[now][s[i]-'a']==-1){
child[now][s[i]-'a']=newNode();
}
f[now]++;
now=child[now][s[i]-'a'];
}
f[now]++;
}
int query(const char s[]){
int len = strlen(s);
int now = root;
for(int i=0;i<len;i++){
if(child[now][s[i]-'a']==-1){
return 0;
}
now = child[now][s[i]-'a'];
}
return f[now];
}
}trie;
char tmp[maxn];
int main(){
int n,m;
while(~scanf("%d",&n)){
trie.init();
for(int i=0;i<n;i++){
scanf("%s",tmp);
trie.insert(tmp);
}
scanf("%d",&m);
while(m--){
scanf("%s",tmp);
printf("%d\n",trie.query(tmp));
}
}
return 0;
}