字典树

因为做题的需要,花了点时间学了字典树。原来字典树是那么的简单,我还以为很难呢。


在我看来,字典树就是为了方便查找。

从下面篇博客就能知道为什么在我看来字典树就是为了查找。

http://blog.youkuaiyun.com/u012501262/article/details/21695033


下面先看字典树的节点的构造:

const int MAX = 26;
//为什么是26,因为是26个字母,如果分大小写那么就是52,如果再加入数字,那就是62
struct node
{
   
    int k;//该变量的类型根据需求变化
    node *next[MAX];//
    node()
    {
        count = 0; 
        flag = 0; 
        for(int i=0;i!=MAX;++i)
        {
            next[i] = NULL;
        }
    }
};


如何建树呢?

给定一个单词,把单词的每个字符作为一个节点,前一个字母是后一个字符的双亲节点。

例如给定一个单词ab

那么就要创建一个一个节点,让root->next[0] = new node;

再 root->next[0]->next[1] = new node;

字典树是根据next的指向是否为空来判断该字母是否存在.


下面是建树:

class trie//字典树类
{
public:
    trie(){root = new node;}
    void creat_trie(string str);
    int search(string str);
    void print_all();
private:
    node *root;
};


void trie ::creat_trie(string str)//字典树的创建
{
    node *current = root;
    node *fresh;
    int index;
    for(int i=0;i<str.size();++i)
    {
        index = str[i] - 'a';
        if(current->next[index] == NULL)//如果next的指向为空,该字典树不存在该前缀,要创建
        {
            fresh = new node;
            current->next[index] = fresh;
            current = current->next[index];
            current->k = 1;//该前缀的数量
        }
        else
        {//如果不为空,则增加该前缀的数量
            current = current->next[index];
            current->k++;
        }
    }


}
懂得建树,就明白如何查找了

下面是查找:


int trie:: search(string str)
{
    node *current;
    current = root;
    int index;
    for(int i=0;i!=str.size();++i)
    {
        index = str[i] - 'a';
        current = current->next[index];
        if(current == NULL)//如果指向为空,则字典树中不存在以str为前缀的单词
            return 0;
    }
    if(current != NULL)//存在
        return current->k;//返回以str为前缀的单词的数量

}



完整的程序:

#include<iostream>
using namespace std;
const int MAX = 26;
struct node
{
    int k;//根据需求改变
    node *next[MAX];
    node()
    {
        k = 0;
        for(int i=0;i!=MAX;++i)
        {
            next[i] = NULL;
        }
    }
};

class trie//字典树类
{
public:
    trie(){root = new node;}
    void creat_trie(string str);
    int search(string str);
    void print_all();
private:
    node *root;
};

void trie ::creat_trie(string str)//字典树的创建
{
    node *current = root;
    node *fresh;
    int index;
    for(int i=0;i<str.size();++i)
    {
        index = str[i] - 'a';
        if(current->next[index] == NULL)
        {
            fresh = new node;
            current->next[index] = fresh;
            current = current->next[index];
            current->k = 1;
        }
        else
        {
            current = current->next[index];
            current->k++;
        }
    }

}

int trie:: search(string str)
{
    node *current;
    current = root;
    int index;
    for(int i=0;i!=str.size();++i)
    {
        index = str[i] - 'a';
        current = current->next[index];
        if(current == NULL)
            return 0;
    }
    if(current != NULL)
        return current->k;

}


int main()
{
    trie t;
    string str;
    getline(cin,str);
    while(str != "")
    {
        t.creat_trie(str);
        getline(cin,str);
    }
    while(getline(cin,str))
    {
        cout<<t.search(str)<<endl;
    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值