字典树(Trie)

字典树,是一种树形结构,是一种哈希树的变种。经常被搜索引擎系统用于文本词频统计。
对cat,cash,app,apple,aply,ok 建一颗字典树,建成之后如下图所示

字典树(Trie)_第1张图片

思路

从图中可以直观看出,从左到右扫这个单词,如果字母在相应根节点下没有出现过,就插入这个字母;否则沿着字典树往下走,看单词的下一个字母。
这就产生一个问题:往哪儿插?计算机不会自己选择位置插,我们需要给它指定一个位置,那就需要给每个字母编号。
我们设数组,表示编号为的节点第个孩子编号为的节点
什么意思呢?
这里有2种编号,一种是表示节点的位置编号,这是相对整棵树而言的;另一种是,表示节点的第的孩子,这是相对节点而言的。
不理解?看图
还是单词cat,cash,app,apple,aply,ok
我们就按输入顺序对其编第一种号,红色表示编号结果。因为先输入的cat,所以c,a,t分别是1,2,3,然后输入的是cash,因为c,a是公共前缀,所以从s开始编,s是4,以此类推。
注意这里相同字母的编号可能不同(因为它们的父节点不同)

字典树(Trie)_第2张图片

第二种编号,相对节点的编号,紫色表示编号结果。
因为每个节点最多有26个子节点,我们可以按他们的字典序从0——25编号,也就是他们的ASCLL码-a的ASCLL码。
注意这里相同字母的编号相同 (减去‘a'肯定一样啊)
字典树(Trie)_第3张图片

回到数组 。 数组 ,表示编号为 的 节点的第 个 孩子是编号为 的 节点
那么第二种编号即为 ,第一种编号即为
字母编号之所以从节点1开始,是因为节点0的第i个孩子是新单词的开始

构建字典树

void init( )
{
    pos=1;//初始化,编号为1开始
    memset(tree,0,sizeof(tree));//初始化
    memset(num,0,sizeof(num));
    memset(vis,0,sizeof(vis));
}
void insert(string s)
{
    int len=s.size( );
    //int len=strlen(s);
    int root=0;//新单词root为0,表明是一个新单词,现在知道图中编号要从1开始了吧!!
    for(int i=0;i

查询

1. 查询在字符串集合中是否有以字符串s为前缀的字符串

int find(char *s)//查找是否有以字符串s为前缀的单词
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i

2. 查询在字符串集合中有多少个以字符串s为前缀的字符串

int findsum(char *s)//查找以字符串s为前缀的单词有多少个
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i

3. 查找并输出每个字符串在字符串集合里面唯一确定的最短前缀(前缀不能有歧义)
Shortest Prefixes

void findminpre(string s)//查找字符串s唯一可以确定的最短前缀
{
    //int len=strlen(s);
    int len=s.size( );
    int root=0;
    for(int i=0;i

4. 判断字符串集合中的字符串否是字符串集合其他字符串的前缀
Phone List

bool judgepremix(char *s)//判断字符串是不是字符串集某个字符串的前缀
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i

5.判断字符串集合中的字符串是否是字符串集合其他两个字符合并的
Hat’s Words

bool findprefix(char *s)//判断字符串是否由串集里的两个字符串构成
{
    int len=strlen(s);
    int root=0;
    for(int i=0;i
完整代码
#include
#include
#include
#include
using namespace std;
const int M=10010;
int tree[M][26];
int pos;
int num[M];
int vis[M];
mapmp;
void init( )
{
    pos=1;
    memset(tree,0,sizeof(tree));
    memset(num,0,sizeof(num));
    memset(vis,0,sizeof(vis));
}
void insert(string s)
{
    int len=s.size( );
    //int len=strlen(s);
    int root=0;
    for(int i=0;i>s)
    {
        insert(s);
        mp[++cnt]=s;
    }
    for(int i=1;i<=cnt;i++)
    {
        cout<

你可能感兴趣的:(字典树(Trie))