应用
如何把单词存入一个字典来纠正拼写呢?对于某个给定的单词,我们希望很快在字典中找到一个最接近的词。如果把字典里的所有单词存在一个散列表里,单词之间的一切相近性信息都将丢失。所以,更好的方式是把这些单词存入字典树,字典树也叫前缀树或排序树(trie tree)。
定义
一棵保存了某个单词集合的树称为字典树。连接一个节点及其子节点的弧线用不同字母标注。因此,字典中的每个单词与树中从根节点到树节点的路径相关。每个节点都是标记,用于区分相关字母组合究竟是字典中的单词,还是字典中单词的前缀(图 2.2)。
字典树存储着法语单词 as、port、pore、pré、près 和 prêt(但没有重音符号)。图中的虚线圈表示子节点 [①] ;实线圈代表字典中一个完整的单词。右边是一个前缀树代表的相同字典 [②]。
① 这个路径的字母组合只是一个正确拼写的单词前缀。——译者注
② 右侧的树合并了只有一个子节点的路径,经过优化的结构更简洁,效率更高。——译者注
拼写纠正
利用上述数据结构,我们很容易在字典中找到一个与给定单词距离为 dist 的单词。这里的距离以 编辑距离(levenshtein distance)来定义,本书 3.2 节有详细介绍。查找方式是只需模拟每个节点的拼写操作,然后使用参数 dist-1 进行递归调用。
变种
若某个节点只有一个子节点,就可以合并多个节点,这种结构更精简。这种节点用单词标记,而不是用字母标记。图 2.2 右侧的结构更节省内存和遍历时间,被称为前缀树(patricia trie)。
class Trie_Node:
def __init__(self):
self.isWord = False
self.s = {c: None for c in ascii_letters}
def add(T, w, i=0):
if T is None:
T = Trie_Node()
if i == len(w):
T.isWord = True
else:
T.s[w[i]] = add(T.s[w[i]], w, i + 1)
return T
def Trie(S):
T = None
for w in S:
T = add(T, w)
return T
def spell_check(T, w):
assert T is not None
dist = 0
while True: # 尝试用越来越长的距离来查找
u = search(T, dist, w)
if u is not None:
return u
dist += 1
def search(T, dist, w, i=0):
if i == len(w):
if T is not None and T.isWord and dist == 0:
return ""
else:
return None
if T is None:
return None
f = search(T.s[w[i]], dist, w, i + 1) # 相关
if f is not None:
return w[i] + f
if dist == 0:
return None
for c in ascii_letters:
f = search(T.s[c], dist - 1, w, i) # 插入
if f is not None:
return c + f
f = search(T.s[c], dist - 1, w, i + 1) # 替换
if f is not None:
return c + f
return search(T, dist - 1, w, i + 1) # 删除
作者:图灵教育
链接:https://leetcode-cn.com/leetbook/read/programmation-efficace/94bas5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
在这里插入代码片
作者:图灵教育
链接:https://leetcode-cn.com/leetbook/read/programmation-efficace/94bas5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:图灵教育
链接:https://leetcode-cn.com/leetbook/read/programmation-efficace/94bas5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*作者:图灵教育
链接:https://leetcode-cn.com/leetbook/read/programmation-efficace/94bas5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*