zoukankan      html  css  js  c++  java
  • 字典树(tried)前缀树

    字典树又称为前缀树,是一种用来统计字符串前缀数目的数据结构,字典树的实现相对于线段树等数据结构还是比较简单。

    字典树的有3个核心函数,insert , search ,delete。

    实现字典树常用的方式有俩种,一个是结构体+指针,还用一种是二维数组模拟,思想都是一样的。

    1、首先定义字典树的节点:

    class node{
    public:
        int path;
        int end;
        node *mp[26];
        node (){
            path=end=0;
            for (int i=0;i<26;i++) 
                mp[i]=NULL;
        }
    };

       节点中的path用来记录该节点被几个字符串用过。end用来记录以该节点结尾的字符串的个数。node *mp[26]是一个指针数组,我们可以用该数组记录该节点指向的下一个节点,数组大小为26指的是从a~z 26个英文字母,这个可以根据自己的寻求更改。比如说 x->mp[i]指的是节点x指向下一个值为i的节点。

    2、节点的插入。

    node *root = new node();
    void insert(string s){
        node *now=root;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a';
            if(root->mp[id]==NULL){
                root->mp[id]=new node();
            }
            root=root->mp[id];
            root->path++;
        }
        root->end++;
        root=now;
    }

     

    首先定义一个根节点指针。然后遍历字符串S的每一个字符,root->mp[id]!=NULL,说明遍历到目前为止,前缀字符串曾经出现过,即我们之前保存过的字符串和该字符串有共同的前缀。 如果root->mp[id]==NULL,说明该前缀第一次出现,要新申请一个节点用来保存当前字符,并作为上一个节点的儿子节点。root->path++; path记录的是该节点被几个字符串用过。没用一次+1就可以了。插入完之后 root->end++; 说明该节点为当前字符串的终止节点。

    3、字符串的查找

    int search(string s){
        node *now=root;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a';
            if(now->mp[id]!=NULL){
                now=now->mp[id];
            }
            else return 0;//不存在. 
        }
        return now->path;
    }

       查找保存过的字符串无非就是根据字符串s,从root出发能不能找到一条路径。如果找着找着没路了,即S没有遍历完遇到了NULL,那就没找到喽,否则返回path,意思的有树中哟普几个以该字符串为前缀的字符串。

    4、字符串的删除

    void de(string s){
        node *now=root;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a'; 
            root->mp[id]->path--;
            if(root->mp[id]->path==0){
                root->mp[id]=NULL;
                return ;
            }
            root=root->mp[id];
        }
        root->end--;
        root=now;
    }

       如果我们想要删除之前保存过的字符串,只需要修改每个节点的path,如果说该节点的path为0了,直接将指针指为空即可并退出,如果没有遇到path=0的情况,在最后节点的end--,说明以该节点为结尾的字符串减一。

    class node{
    public:
        int path;
        int end;
        node *mp[26];
        node (){
            path=end=0;
            for (int i=0;i<26;i++) 
                mp[i]=NULL;
        }
    };
    node *root = new node();
    void insert(string s){
        node *now=root;
        if(root==NULL) return ;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a';
            if(root->mp[id]==NULL){
                root->mp[id]=new node();
            }
            root=root->mp[id];
            root->path++;
        }
        root->end++;
        root=now;
    }
    int search(string s){
        node *now=root;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a';
            if(now->mp[id]!=NULL){
                now=now->mp[id];
            }
            else return 0;//不存在. 
        }
        return now->path;
    }
    void de(string s){
        node *now=root;
        int n=s.size();
        for(int i=0;i<n;i++){
            int id=s[i]-'a'; 
            root->mp[id]->path--;
            if(root->mp[id]->path==0){
                root->mp[id]=NULL;
                return ;
            }
            root=root->mp[id];
        }
        root->end--;
        root=now;
    }
    
            root->path++;
  • 相关阅读:
    NLP-Progress记录NLP最新数据集、论文和代码: 助你紧跟NLP前沿
    深度学习、图像识别入门,从VGG16卷积神经网络开始
    反向传播神经网络极简入门
    R语言中的遗传算法详细解析
    模拟退火算法
    TensorFlow利用A3C算法训练智能体玩CartPole游戏
    伯克利推出「看视频学动作」的AI智能体
    深度强化学习资源介绍
    Introducing Deep Reinforcement
    库、教程、论文实现,这是一份超全的PyTorch资源列表(Github 2.2K星)
  • 原文地址:https://www.cnblogs.com/Accepting/p/14073138.html
Copyright © 2011-2022 走看看