acwing835Trie字符串统计,字典树(模板题)

字典树就是用树的方式记录单词,大幅度提高单词存储和查找的效率
我一开始想每个节点包括1个char和多个指针,然后每次遍历到该点时再遍历它的指针所指的字母,
然后发现下面这个视频里北大硕士的空间换时间妙:
他的做法:
因为只有26个英文字母,所以最多26个指针,且字母是有顺序的只要把下个字母-‘a’就可用o(1)复杂度知道是否存在该字母,字母在地址
设son【先字母地址】【下个字母】存下个字母的地址
板子:
#include <bits/stdc++.h>

using namespace std;

const int N=100005;
int n,son[N][26],cnt[N],idx;
//son[i][j]记录第i个字母的下个字母在第几号位置上,26个英语字母如下个是a就在0,cnt记入以这个结尾单词有几个 
char str[N];
char op[5];

void Insert(char a[]){
	int p=0;//指针 
	for(int i=0;str[i];i++){
		int t=a[i]-'a';//下个字母 
		if(!son[p][t]) son[p][t]=idx++;
		p=son[p][t]; //指针指向下个指针 
	}
	cnt[p]++;//a[]单词字典树处理完毕,对应单词数+1 
}

int Query(char a[]){
	int p=0;
	for(int i=0;str[i];i++){
		int t=a[i]-'a';
		if(!son[p][t]) return 0;//如果中途就没字母,直接返回0 
		p=son[p][t];
	}
	return cnt[p];//字典树中找到单词对应位置p,返回单词的cnt 
}
int main(int argc, char** argv) {
	cin>>n;
	idx=1;
	for(int i=0;i<n;i++){
		scanf("%s",op);
		scanf("%s",str);
		if(op[0]=='I') Insert(str);
		else cout<<Query(str)<<endl;
	}
	return 0;
}



全部评论

相关推荐

菜菜咪:1. 可以使用简历网站的模版,美观度会更好一点 2. 邮箱可以重新申请一个,或者用qq邮箱的别名,部分hr可能会不喜欢数字邮箱 3. 项目经历最好分点描述,类似的项目很多,可以参考一下别人怎么写的 4. 自我评价可加可不加,技术岗更看重技术。最后,加油,优秀士兵
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务