(数据结构)Trie树(字典树)以及应用以及入门题

Trie树(也叫前缀树)

其实我不知道要去写什么。。。特点:典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 以上都是我想告诉大家的!!!

// ch[i][j] 表示的就是第i个结点编号为j的子结点
const int maxnode = 2e6+5 , sigma_size = 28;
struct node{
	int ch[maxnode][sigma_size];	
	int val[maxnode];			
	int sum[maxnode];		//		出现的次数 
	int tot;				//		结点个数
	void init()	{		tot = 1;	memset(ch[0],0,sizeof(ch[0]));	memset(sum,0,sizeof(sum)); 	}
	int idx(char c)	 {	return  c - 'a';	}
	void insert(char *s, int v){
		int u = 0, n =strlen(s);
		for(int i = 0; i < n; i++){
			int id = idx(s[i]);
			if(!ch[u][id]){								//	结点不存在 
				memset(ch[tot],0,sizeof(ch[tot]));
				val[tot] = 0;				
				ch[u][id] = tot++;			//	新的结点 
			}
			sum[ch[u][id]]++;
			u = ch[u][id];
		}
		val[u] = v;
	}
	int query(char *s, int pos){
		int n = strlen(s), u = 0;
		for(int i = 0; i < n; i++){
			int id = idx(s[i]);
			if(!ch[u][id])	return 0;
			u = ch[u][id];
		}
		return sum[u];
	}	
}T; 

字典树第一题

题目传送门Hdu1251
题意:统计以某个串为前缀的单词个数!
我的理解:好像就是裸的Trie! 增加一个sum数组,sum[i]表示的就是i结点的子结点的个数! 然后跑一边这个Trie树!

AC代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
//#define memset(a,v)  memset(a,v,sizeof(a))
#define X (sqrt(5)+1)/2.0  //Wythoff
#define Pi acos(-1)
#define e  2.718281828459045
#define eps 1.0e-8
#define N 300010
using namespace std;
typedef long long int ll;

const int maxnode = 2e6+5 , sigma_size = 28;
struct node{
	int ch[maxnode][sigma_size];	
	int val[maxnode];
	int sum[maxnode];		//		出现的次数 
	int tot;				//		结点个数
	void init()	{		tot = 1;	memset(ch[0],0,sizeof(ch[0]));	memset(sum,0,sizeof(sum)); 	}
	int idx(char c)	 {	return  c - 'a';	}
	// 插入字符串s,附加的信息是v,注意v必须为非0,0表示的就是‘本节点不是单词结点’ 
	void insert(char *s, int v){
		int u = 0, n =strlen(s);
		for(int i = 0; i < n; i++){
			int id = idx(s[i]);
			if(!ch[u][id]){								//	结点不存在 
				memset(ch[tot],0,sizeof(ch[tot]));
				val[tot] = 0;				
				ch[u][id] = tot++;			//	新的结点 
			}
			sum[ch[u][id]]++;
			u = ch[u][id];
		}
		val[u] = v;
	}
	int query(char *s, int pos){
		int n = strlen(s), u = 0;
		for(int i = 0; i < n; i++){
			int id = idx(s[i]);
			if(!ch[u][id])	return 0;
			u = ch[u][id];
		}
		return sum[u];
	}	
}T; 


int main(){
	
	T.init();
	char a[2000005];
	while(gets(a)){
		if(a[0] == '\0')	break;
		T.insert(a,1);
	}
	while(scanf("%s",a)!=EOF){
		printf("%d\n",T.query(a,1000));
	}
	return 0;
}

字典树第二题

题目传送门Hdu1251
题意:统计以某个串为前缀的单词个数!
我的理解:好像就是裸的Trie! 增加一个sum数组,sum[i]表示的就是i结点的子结点的个数! 然后跑一边这个Trie树!

持续更新!!!

猜你喜欢

转载自blog.csdn.net/qq_43127921/article/details/89505297
今日推荐