数据结构:字典树模板

点击查看代码块
/*
trie树(前缀树)
trie[maxnNode][charSet]
trie[i][j] == 0 表示trie树中的第i号节点,没有连边
trie[i][j] == x 表示trie树中的第i号节点,与树中的第x号节点有一条连边,边权为字符集中的第j个字符 
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
const int charset = 30;
int trie[maxn][charset];
int tot;//trie中节点的个数 
int color[maxn]={0};
int a[maxn];

//insert的时间复杂度 :O(len(s)) 
void insert(char *s){//在字典树中插入字符串s 
	int len = strlen(s);
	int p = 0;//从根节点开始 
	for (int i=0;i<len;i++){
		int c=s[i]-'a';
		if(!trie[p][c]){//树中没有节点p向外连的边权为c的边 
			trie[p][c]=++tot;
		}
		a[trie[p][c]]++;
		p=trie[p][c];
	}
	color[p]=1;//标记最后的节点为p 
}

//search的时间复杂度 :O(len(s))
int search(char *s){//在字典树中查找s字符串 
	int len=strlen(s);
	int p=0;
	for (int i=0;i<len;i++){
		int c = s[i]-'a';
		if(!trie[p][c]) return 0;//字符不匹配,找不到这样的字符串 
		p = trie[p][c];
	}
//	return color[p]=1;//如果p的color为1,表明到达了叶子节点,说明这样的字符串存在
	return a[p];
}

char ss[maxn];

int main(){
	while(gets(ss)){
		if(ss[0] == '\0') break;
		insert(ss);
	}
	while(cin>>ss){
		int ans = search(ss);
		printf("%d\n",ans);
	}
	return 0;
}   
posted @ 2020-07-31 21:23  wsl_lld  阅读(84)  评论(0编辑  收藏  举报