首页 > 代码库 > Trie树模板

Trie树模板

百度资料一大堆,编码过程中要注意这几个数组维护(貌似ACM中树都是用数组——线段树,脸是前向星实现的)

    int sz;//节点编号,累加量
    int ch[Word_Len][sigma_size];//Trie树
    int Have_Word[Word_Len];//该节点下的单词个数
    int val[Word_Len];//路径长度
    int pre[Word_Len];//表示这个节点的前驱
    char he[Word_Len];//表示这个节点是哪个词


模板:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
#define inf 0x3f3f3f3f
#define maxn 100+10000


#define sigma_size 95
#define Word_Len 50500
struct Tire
{
    int sz;//节点编号
    int ch[Word_Len][sigma_size];//Trie树
    int Have_Word[Word_Len];//该节点下的单词个数
    int val[Word_Len];//路径长度
    int pre[Word_Len];//表示这个节点的前驱
    char he[Word_Len];//表示这个节点是哪个词
    int NewNode(){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=Have_Word[sz]=0; return sz++; }
    void init(){ sz=1; NewNode(); }// 给根节点一个位置
    int idx(int x){return x-32;}

    int insert(char *s)
    {
        int u=0;
        for(int i=0;s[i];i++)
        {
            int c=idx(s[i]);
            if(!ch[u][c])//节点不存在,新建节点
            {
                ch[u][c]=NewNode();
                he[sz-1]=s[i];
                val[sz-1]=val[u]+1;
                pre[sz-1]=u;
            }
            u=ch[u][c];
<span style="white-space:pre">	</span>    Have_word[u]++;//这句的先后顺序也很重要。记录以这个点为根的串有几个
        }
        return u;
    }
    int find_word(char *s)
    {
        int u=0;
        for(int i=0;s[i];i++)
        {
            int c=idx(s[i]);
            if(!ch[u][c]) return 0;
            u=ch[u][c];
        }
        return Have_Word[u];
    }
    void have_name(char *s,int now)
    {
        int len=val[now],cc=now;
        s[len--]=0;
        while(cc)
        {
            s[len--]=he[cc];
            cc=pre[cc];
        }
    }

}ac;

POJ 2001、

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <math.h>
#include <queue>
#define ll int
using namespace std;
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}

#define Word_Len 10000
#define Sigma_size 30

int ch[Word_Len][Sigma_size];	 //Word_Len是字典树的节点数 若都是小写字母Sigma_size=26
int Have_word[Word_Len];		 //这个节点下有几个单词
int val[Word_Len];				 // 这个节点附带的信息,初始化为0表示这个节点不存在单词,所以节点带的信息必须!=0
int sz ;						 //当前节点数
//初始化字典树
void init(){
	sz = 1;
	memset(ch[0], 0, sizeof(ch[0]));
	memset(val, 0, sizeof(val));
	memset(Have_word, 0, sizeof(Have_word));
}//初始化
int idx(char c){ return c-'a';}	 //字符串编号

void Creat(char *s){
	int u = 0, len = strlen(s);
	for(int i = 0; i < len; i++){
		int c = idx(s[i]);
		if(!ch[u][c]){		     //节点不存在
			memset(ch[sz], 0, sizeof(ch[sz]));
			ch[u][c] = sz++;
		}
		u = ch[u][c];//这个先后顺序也会影响结果
		Have_word[u]++;
	}
}
void find_ans(char *s){
	int u = 0, len = strlen(s);
	for(int i = 0; i < len; i++){
		int c = idx(s[i]);
		u = ch[u][c];
		printf("%c",s[i]);
		if(Have_word[u]==1) return ;
	}
}


char S[1002][25];
int n;
int main(){
	n=0;
	init();
	while(~scanf("%s",S[n])){
		Creat(S[n]);
		n++;
	}
	for(int i=0;i<n;i++){
		printf("%s ",S[i]);
		find_ans(S[i]);
		printf("\n");
	}

	return 0;
}



Trie树模板