理解字符串查找之前缀树

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_43152052/article/details/100585638

前缀树的定义:
又称单词查找树,字典树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高

前缀树的性质:

  • 1)根节点不包含字符,除根节点外每一个节点都只包含一个字符
  • 2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
  • 3)每个节点的所有子节点包含的字符都不相同
    在这里插入图片描述
    注:每个节点都含有26个链接表示出现的26个小写字母,即每个节点表示的字符是26个字符中的一个,当字符串插入完成时,我们就会标记该字符串就是完整的字符串了。

在这里插入图片描述

在这里插入图片描述

前缀树的操作:
前缀树的主要操作为插入,查找,删除(删除操作很少见)

源码如下:提供插入,查找及字符串的前缀字符操作

#include <iostream>
#include <string>
using namespace std;

class Trie {
private:
    bool is_string;//当前节点是否为一个完整的字符串
    Trie *next[26];//每个节点有26链接
public:
    
    /** Initialize your data structure here. */
    Trie() {
        is_string=false;
        memset(next,0,sizeof(next));//为next分配4个字节的内存空间
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* root=this;//根节点,根节点的节点值为空
        for(const auto & w:word)//遍历字符串的每一个字符,若下一个节点不存在,则添加一个新节点
        {
            if(root->next[w-'a']==nullptr){root->next[w-'a']=new Trie();}
            root=root->next[w-'a'];//根节点更新为新节点
        }
        root->is_string=true;//该字符串为完整的字符串
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* root=this;//根节点
        for(const auto & w:word)//遍历字符串,root每次更新为字符串中的节点值
        {
            if(root!=nullptr)root=root->next[w-'a'];
        }
        return (root!=nullptr&&root->is_string);
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* root=this;//根节点
        for(const auto & w:prefix)//遍历字符串,root每次更新为字符串中的节点值
        {
            if(root!=nullptr)root=root->next[w-'a'];
        }
        return (root!=nullptr);
    }
};

int main()
{
    Trie* trie = new Trie();
    trie->insert("apple");
    cout << trie->search("apple") << endl;
    cout << trie->search("app") << endl;
    cout << trie->startsWith("app") << endl;
    trie->insert("app");
    cout << trie->search("app") << endl;
    system("pause");
}

前缀树的应用:

1、自动补全
在这里插入图片描述
2、拼写检查
在这里插入图片描述
3、IP路由(最长前缀匹配)
在这里插入图片描述
4、九宫格打字预测
在这里插入图片描述
5、单词打字游戏
在这里插入图片描述

前缀树与其他数据结构的优点:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43152052/article/details/100585638
今日推荐