题干:
给定N个字符串S1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。
输入字符串的总长度不超过
1
0
6
10^6
106,仅包含小写字母。
输入格式
第一行输入两个整数N,M。
接下来N行每行输入一个字符串SiSi。
接下来M行每行一个字符串T用以询问。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
输入样例:
3 2
ab
bc
abc
abc
efg
输出样例:
2
0
思路:
题意为给你N个字符串,再进行M次询问,每次询问为输入一个字符串,求N个字符串集合中,该字符串的前缀有几个。因为前缀需要从从前向后找,所以可以考虑到用字典树来解决这道题,为N个字符串的集合建立一颗字典树,然后记录每个字符串的结束位置,用来统计个数。
#include <bits/stdc++.h>
using namespace std;
#define eps 1e-5
const int mx=100100;
char ch[mx];
int a[mx][30],n,m,cnt[mx],tot;
void insert()
{
int s=0;//头结点设为0
for(int i=0;i<strlen(ch);i++){
if(a[s][ch[i]-'a']==0){
a[s][ch[i]-'a']=++tot; //记录下个字符的位置
}
s=a[s][ch[i]-'a']; //记录当前指针
}
cnt[s]++; //统计个数
}
int query(){
int ans=0,p=0;
for(int i=0;i<strlen(ch);i++){
p=a[p][ch[i]-'a'];
if(p==0) return ans;
ans+=cnt[p];
//printf("%d\n",cnt[p]);
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%s",ch);
insert();
}
for(int i=0;i<m;i++){
scanf("%s",ch);
printf("%d\n",query());
}
return 0;
}