字典树

 

 

http://acm.hdu.edu.cn/showproblem.php?pid=1251

/**
字典树的第一个结点不装任何数据
一个结点 能够装 26 个字母
a[i][j] = value 表示第i(到J字母的母结点字母索引位置)个结点到 的 j(就是对应的此时字母) 为value (对应此时的字母j)的索引位置 
**/
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int max_size=26;
const int maxn =2e6+5;//

int tree[maxn][max_size]; //记录的该点的下一个子结点的位置 maxn代表的每个结点(对应层数 )的索引
bool flag[maxn];
int num[maxn];
int pos; //记录下一层的位置
void insert_Tree(char *str){
	int root=0;
	for(int i=0;i<strlen(str);i++){
		int index = str[i]-'a'; //对应字母的acall码
		if(!tree[root][index]){
			tree[root][index]=++pos;//相当于  记录对应字母index(对应的ascall字母)所拥有的层数index(一层能容纳26个字母)

		}
		root=tree[root][index]; (相当于root = root -> next 进入下一层)
		num[root]++;
	}
	flag[root]=true; //表示这个位置存在一个单词

}
int select_tree(char * str){
	int root=0;
	for(int i=0;i<strlen(str);i++){
		int index=str[i]-'a';
		if(!tree[root][index]){
			return 0;
		}
		root=tree[root][index];
	}
	return num[root];
}
//此题用初始化会导致内存超限
void init(){
    for(int i=0;i<maxn;i++){
        flag[i]=false;
        num[i]=0;
        for(int j=0;j<max_size;j++){
            tree[i][j]=0;
        }
    }
    pos=0;

}
int main(){

	pos=0;
	char ss[maxn];
	ios::sync_with_stdio(false);
	//string str1;
	while(gets(ss))
	{
        if(ss[0]=='\0') break;  //表示一个字符串的结束标志
        insert_Tree(ss);
	}
	while(gets(ss)){
        if(ss[0]=='\0') break;
    	printf("%d\n",select_tree(ss));
	}

	return 0;
}

 

http://acm.hdu.edu.cn/showproblem.php?pid=2072

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<sstream>
using namespace std;
int  const maxn=2e6+5;
int const maxsize=30;
int tree[maxn][maxsize];
bool flag[maxn];
int pos;
void insert_Tree(string str){
	int root =0;
	for(int i=0;i<str.size();i++){
		int index = str[i]-'a';
		if(!tree[root][index]){
			tree[root][index]=++pos;
		}
		root=tree[root][index];
	}
	flag[root]=true;	
}
bool find(string str){
	int root=0;
	for(int i=0;i<str.size();i++){
		int index=str[i]-'a';
		if(!tree[root][index]) return true;
		root=tree[root][index];
	}
	if(flag[root]){
		return false;
	}else{
		return true;
	} 
}
string str1,str2;
int main(){
	ios::sync_with_stdio(false);
	while(getline(cin,str1)){
		if(str1=="#")	break;
		int count=0;
		stringstream ss(str1); //读取str中的单字,比如hello world ,就会读取hello和world。
		while(ss>>str2){
			if(find(str2)){
				count++;
				insert_Tree(str2);
			}
		}
		cout<<count<<endl;
//		for(int i=0;i<maxn;i++){    //此处位置初始化 出现错误 初始化时只需要初始化结点数目就可以了
//									//并不需要全部点都初始化
//									 
//			flag[i]=false;
//			for(int j=0;j<maxsize;j++){
//				tree[i][j]=0;
//		}
	for(int i=0;i<pos;i++){    //此处位置初始化 出现错误 初始化时只需要初始化结点数目就可以了
									//并不需要全部点都初始化							 
			flag[i]=false;
			for(int j=0;j<maxsize;j++){
				tree[i][j]=0;
		}
		
	}
	pos=0;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值