阅读 123

字典树学习与应用

前言

最近在使用公司的系统发现智能问答系统的输入提醒挺有意思。具体的效果类似百度搜索时候的文本提醒。今天就研究一下具体的实现,主要的数据结构就是字典树

先看看具体要实现的效果(这里以百度搜索为例):

image.png

解读一下:通过输入文字联想到想要搜索的文字。非常适合特定领域以及知识库的搜索。

正文

字典树简介

字典树,英文名 trie。顾名思义,就是一个像字典一样的树。

字典树的特点如下:

  • 根节点不包含字符,除根节点外每一个节点都只包含一个字符。

  • 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

  • 每个节点的所有子节点包含的字符都不相同。

image.png

如图即为一颗字典树 1->2->6->11 即为字符串 aba。

字典树的实现

具体的实现可以参考 letcode

字典树的应用

如前言中的图片展示,可以用在搜索时候的自动补齐。下面就用 Python 实现一颗字典树,除了基本的功能外,完成数据的自动推荐。

class Trie:     def __init__(self):         self.root = {}              def insert(self, word: str) -> None:         node = self.root         for s in word:             if s in node.keys():                 node = node[s]             else:                 node[s] = {}                 node = node[s]         node['is_word'] = True                      def search(self, word: str) -> bool:         node = self.root         for s in word:             if s in node.keys():                 node = node[s]             else:                 return False                  if 'is_word' in node.keys():             return True         else:             return False              def startsWith(self, prefix: str) -> bool:         node = self.root         for s in prefix:             if s in node.keys():                 node = node[s]             else:                 return False                  return True          def startsWithWords(self, prefix: str):         node = self.root         for s in prefix:             if s in node.keys():                 node = node[s]             else:                 return [""]         res = []         self.printWords(node, prefix, res)                  return res          def printWords(self, node: dict, start: str, res):         if node.get('is_word'):             res.append(start)             return          for k in node.keys():             self.printWords(node[k], start+k, res) 复制代码

下面就手动插入数据进行测试,结果如下:

t = Trie() t.insert("餐饮发票") t.insert("加班餐费怎么报销") t.insert("打车发票怎么获取") t.insert("差旅费用的标准") t.insert("发票邮寄") t.insert("餐饮发票类型的要求") t.insert("发票抬头怎么写") print(t.startsWithWords("发票")) # ['发票邮寄', '发票抬头怎么写'] 复制代码

PS: 这里只演示代码中的实现,具体搜索框的实现感兴趣的小伙伴可以自行封装 API 。

总结

  1. 上面只是介绍基本字典树的实现,这里推荐一个谷歌基于 Python 实现的字典树

简单的使用如下,功能类似为根据前缀匹配出可能的结果:

import pygtrie  t = pygtrie.StringTrie() t['发票'] = '发票' t['发票/快递'] = '发票快递' t['发票/报销'] = '发票报销' t['发票/税率'] = '发票税率' t['餐饮/发票'] = '餐饮发票' t['交通/发票'] = '交通发票' print(t.items(prefix='发票'))  # [('发票', '发票'), ('发票/快递', '发票快递'), ('发票/报销', '发票报销'), ('发票/税率', '发票税率')] 复制代码

  1. 这里关于字典树的实现并没有考虑空间复杂度,关于更多字典树的种类以及实现可以参考  小白详解 Trie 树 。

  2. letcode 上有很多关于字典树的实现,感兴趣的小伙伴可以自行了解。


作者:西红柿蛋炒饭
链接:https://juejin.cn/post/7025508904784101389


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐