Acwing - 142 前缀统计 (Trie 字典树)
原创
©著作权归作者所有:来自51CTO博客作者不想悲伤到天明的原创作品,请联系作者获取转载授权,否则将追究法律责任
142 前缀统计
给定N个字符串S1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。
输入字符串的总长度不超过10^6,仅包含小写字母。
输入格式
第一行输入两个整数N,M。
接下来N行每行输入一个字符串Si。
接下来M行每行一个字符串T用以询问。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
输入样例:
输出样例:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Swap(a,b) a ^= b ^= a ^= b
#define pi acos(-1)
#define cl(a,b) memset(a,b,sizeof(a))
using namespace std ;
const int MAX = 100005 ;
const int inf = 0x3f3f3f3f ;
int trie[MAX][26] , tot = 1 ;
char str[MAX] ;
int cnt[MAX] ;
void insert(char *str){
int len = strlen(str) ;
int p = 1 ;
for(int k = 0 ; k<len ; k++ ){
int ch = str[k] -'a' ;
if(!trie[p][ch] ) trie[p][ch] = ++tot ;
p = trie[p][ch] ;
}
cnt[p]++ ;// 统计到当前字符为止的字符串个数
}
int search(char *str){
int len = strlen(str) ,p = 1 ;
int res = 0 ;
for(int k = 0 ; k<len; k++){
int s = str[k] -'a' ;
if(!trie[p][s]) break ;
p = trie[p][s] ;
res+=cnt[p] ;
}
return res;
}
int main()
{
int n , m ;
cin >> n>>m ;
for(int i = 1 ; i<=n ; i++ ) {
cin >>str;
insert(str) ;
}
int ans = 0 ;
while(m--) {
cin >>str ;
ans = search(str) ;
cout<<ans<<endl ;
}
return 0 ;
}