1601 前缀统计 0x10「基本数据结构」例题
描述
给定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典序题目,考虑到是求前缀字符串个数,所以我们可以对Trie模板做些更改,我们不止需要知道每个节点是否为某个字符串的结束节点,还需要知道有多少个字符串以它为结束位置。于是我们可以将End数组记录有多少字符串以它为结束,于是每次查询时只需要累加当前节点的End值即可。
代码示例
#include<cstdio>
#include<cstring>
const int SIZE = 100000;
int t[SIZE][30],tot = 1,End[SIZE];
void insert(char *str){
int len = strlen(str),p = 1;
for(int k = 0;k < len;k++){
int ch = str[k]-'0';
//1是根节点,所以tot要从2开始
if(t[p][ch] == 0) t[p][ch] = ++tot;
p = t[p][ch];
}
End[p]++;
}
int search(char *str){
int len = strlen(str),p = 1,num = 0;
for(int k = 0;k < len;k++){
p = t[p][str[k]-'0'];
if(p == 0) return num;
num += End[p];
}
return num;
}
int main(){
int n,m;
char str[1000100];
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
scanf("%s",str);
insert(str);
}
while(m--){
scanf("%s",str);
printf("%d\n",search(str));
}
return 0;
}