python中的字典树:创建,搜索,扩展单词,打印字典树
python中的字典结构非常好用,直接利用键赋值tree[key]=value
就可以很容易的创建出树形结构的分支。
字典树经常用来代替list数据类型存储词典数据,即便词典是百万级的数量,字典树也会以很小的计算代价实现搜索。
这里使用面向函数的方法实现字典树(Trie),方便理解和粘贴。
1.创建一个字典树
方法1 直接赋值
# 创建字典方法1
Trie = {"a": "$",
"b": {
"c":
{"g": "$", "h": "$"},
"e":
{"i": "$", "j": "$"},
"f":
{"k": "$", "l": "$"},
}}
方法2 把列表转换为字典树
# 创建字典方法2
lst = ['a', 'bcg', 'bch', 'bei', 'bej', 'bfk', 'bfl']
Trie = {}
for i in lst:
cur_node = Trie
for x in i[:-1]:
if x not in cur_node:
cur_node[x] = {}
cur_node = cur_node[x]
cur_node[i[-1]] = '$'
打印字典树
print(Trie)
我们利用$
作为叶节点的标志,以$
为结束的路径都作为一个完整的单词,不论使用方法1还是方法2,该字典树的结构图如下
字典树结构图
2.在字典树中搜索单词是否存在
获得了树结构的字典,我们必然要考虑如何使用字典树,我们希望能实现红色箭头的搜索过程
字典搜索路径图
利用search
方法搜索word
在Trie
中是否为正确的单词,搜索单词是否存在,找到单词就返回True
# 在字典树中搜索单词是否存在
def search(word):
cur_node = Trie
for i in word:
try:
cur_node = cur_node[i]
except:
return False
return True if cur_node == '$' else False
调用方法
# 路径不存在于字典的情况
print(search('bce'))
# 路径不是完整的单词的情况
print(search('b'))
# 路径是合理的单词的情况
print(search('a'))
print(search('bgj'))
3.补全单词
我们经常会遇到一种情况,我们有一个不完整的单词,我们希望在字典中找到这个以这个不完整单词开头的所有可能,对不完整的单词进行补全
单词补全路径图
红色是访问不完整单词的路径,绿色是补全的路径,通过不完整单词bg
获取到补全单词bgi,bgj
get_start_with
是获取到所有broken_word
的补全单词,返回结果在一个列表中,get_completion_words
通过递归的方式遍历传入节点处的字典
# Author:HeartMaster
# 寻找以broken_word为开头,一直到叶节点的每个路径
def get_start_with(broken_word):
# 以字符串为路径找到最后一个字符在字典中的节点
cur_node = Trie
for i in broken_word:
try:
cur_node = cur_node[i]
# 路径不存在字典中,则直接返回原词
except:
# 搜索单词如果不存在字典树的路径中,我们直接返回这个单词
return [broken_word]
# 递归遍历字典树
def get_completion_words(pre_string, cur_node):
word_list = []
# 叶节点退出递归,返回完整字符串
if cur_node == '$':
word_list.append(pre_string)
return word_list
# 通过字典树的每个分支对之前的字符串进行补充
for key in list(cur_node):
word_list.extend(get_completion_words(pre_string + str(key), cur_node[key]))
# 返回最终结果
return word_list
return get_completion_words(broken_word, cur_node)
调用方法
# 字典中不存在的情况
print(get_start_with('ag'))
# 可以拓展的情况
print(get_start_with('b'))
print(get_start_with('bc'))
print(get_start_with('bfa'))
# 利用递归遍历了整个字典树
print(get_start_with(''))
我们希望这个单词不论是否可以扩展,甚至不存在于字典中,都被返回
4.遍历打印整个字典树
如果传入空字符,这个方法将遍历打印整个字典
print(get_start_with(''))