用Python实现字典树(Trie)与双数组字典树(DATrie)

您所在的位置:网站首页 数组字典树 用Python实现字典树(Trie)与双数组字典树(DATrie)

用Python实现字典树(Trie)与双数组字典树(DATrie)

2024-01-19 09:48| 来源: 网络整理| 查看: 265

1. 字典树(Trie)

假如我们把字典中的词以记录的形式(无序)存入数据库中。现给定一串字符,要查找该字符串是否为字典中的词。因为数据库中的记录是无序的,所以,最朴素的方法就逐记录匹配。此方法简单,但是效率不高。因为每次匹配都必须从首字符开始。当然,可以将数据库中的记录按字符编码进行排序。这样,首字相同的词的记录都聚集在某个区间,匹配首字时直接跳至首字所处的区间开头即可,其它字符的匹配以此类推。其实这种方法的思想就是前缀匹配的思想。但是用数据库实现比较麻烦,可以用字典树这种数据结构来实现。 先来一张示意图,直观感受一下字典树的结构: 字典树

图-1 字典树

例如,要查找“下雪天”是否在字典中,先检查根结点是否存在孩子结点:“下”。如果存在,接下来只需在以”下“为根结点的子树中搜索即可,极大地缩小了检索范围。在自上而下匹配过程中,如果某个字匹配不到结点,说明该词不在字典中,立即结束检索过程。

2. 字典树的代码实现

虽然Python没有指针概念,不过,我们可以用字典来表示结点所拥有的孩子结点。所以,结点类应该有一个成员变量children,它的数据类型是字典。我们再设置一个成员变量用来存储结点的值,代码如下所示:

class Node(object): def __init__(self, value): self._children = {} self._value = value

可以用字符作为字典元素的key,如图-1中圆圈里边的字。用孩子结点的地址作为字典元素的value。在Node类中,我们要实现一个添加孩子结点的方法,其主要功能就是往children字典中添加元素,代码如下:

class Node(object): def __init__(self, value): self._children = {} self._value = value def _add_child(self, char, value, overwrite=False): child = self._children.get(char) if child is None: child = Node(value) self._children[char] = child elif overwrite: child._value = value return child

上述代码中,child=Node(value) 中的child的值就是结点对象的地址。根结点的children变量的值类似长这样:{‘火’: node_1, ‘下’: node_2, ‘适’: node_3} 结点类构建好了,接下来构建字典树类。字典树是由结点构成的,所以字典树类继承结点类。字典树类要有一个方法能够把词语添加到树中。设字典树对象名为trie,那么,也就是要实现这个操作:trie[‘下雪’] = 1,trie[‘下雪天’]=2。这种赋值操作可以用Python的魔法函数__setitem__( )实现。 字典树类还要有查寻功能,即查寻某词是否在字典中。这里我们用这种形式查寻:isExist = trie[‘下午’],根据isExist的值来判断是否查找成功。字典树类的代码如下所示:

class Trie(Node): def __init__(self): super().__init__(None) def __contains__(self, key): return self[key] is not None def __getitem__(self, key): state = self for char in key: state = state._children.get(char) if state is None: return None return state._value def __setitem__(self, key, value): state = self for i, char in enumerate(key): if i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3