背景和定义:
在算法导论中,Trie并不叫字典树,而是叫基数树,也就是说实际上并不是只是和字符串有关。字典树的构造结果如果说和字符串本身没有关系的话,实际上是一个N叉树。在这个N叉树上,如果是共父节点的N个子节点是有序 的,这样构造出来的树实际上就和字典树很像了。
进行了大规模的合并.从而大量的节省了时间.
我们直接看构造的方法可能更好理解一点.
按照我们前面的说法,首先是我们先加上一个struct的节点:
struct node
{
node *nxt[26];
int flag;
node()
{
for(int i=0;i<26;i++)
{
nxt[i]=NULL;
}
flag=0;
}
};
随后我们开始构造字典树,将字典树加在后面的叶子上面:
void ins (char *s)
{
int len=strlen(s);
node *now=root;//指向根节点
for(int i=0;i<len;i++)
{
int to=s[i]-'a';
if(now->nxt[to]==NULL)now->nxt[to]=new node();
now=now->nxt[to];//now指向新生成的结点
}
now->flag++;//最后一个叶节点做标记 意思是这个字符串在这个结点结束
}
最后的匹配的结果就是按照root位置向后正常的走
接下里是一个简单的例题:hihocoder 1366
一些技巧和其他类型的问题:
1. 求最短的区别前缀(POJ 2001)
思路非常简单,只要在字典树上记录所有的节点的记录次数,这个时候只要查到一个次数只有1的时候就可以了。
poj2001题解
2. 空间不够导致RE的问题 (BZOJ 1174)
这个题没法交,大家YY吧
题意:给你一个字符集合,你从其中找出一些字符串出来. 希望你找出来的这些字符串的最长公共前缀*字符串的总个数最大化
这道题最要命的不是因为算法困难,而是空间开不下。考虑到我们的Trie本身也是一棵树,也就是说我们可以用建树的方法进行建树,而不是直接开好所有的内存和指针.