[题]前缀统计——标签 #trie

题目

  1. 给定N个字符串S1,S2…SN,接下来进行M次询问,每次询问给定一个字符串T,求S1~SN中有多少个字符串是T的前缀。
    输入字符串的总长度不超过106,仅包含小写字母。
  2. 输入格式
    第一行输入两个整数N,M。
    接下来N行每行输入一个字符串Si。
    接下来M行每行一个字符串T用以询问。
  3. 输出格式
    对于每个询问,输出一个整数表示答案。
    每个答案占一行。
  4. 输入样例:
    3 2
    ab
    bc
    abc
    abc
    efg
  5. 输出样例:
    2
    0
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e6 + 10;
int pos = 1, trie[N][26], num[N];
int n, m;

void isert(string s){
	int c = 0;//c最终会到达该串最后一个字符在trie地图上该到的位置 
	for(int i = 0; i < s.size(); i ++){
		int j = s[i] - 'a';
		if(trie[c][j] == 0)
			trie[c][j] = pos ++;
		c = trie[c][j];
	}
	num[c] ++;//这里将插入的串当做一个整体,因为它是前缀
}

int fnd(string s){
	int c = 0, ans = 0;
	for(int i = 0; i < s.size(); i ++){
		int j = s[i] - 'a';
		if(!trie[c][j]) break;
		c = trie[c][j];
		ans += num[c];
	}
	return ans;
}

int main() {
	cin >> n >> m;
	while(n --){
		string s;
		cin >> s;
		isert(s);
	} 
	while(m --){
		string s;
		cin >> s;
		cout << fnd(s) << endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值