在Python中删除特定trie实现中的单词

时间:2013-07-31 20:03:14

标签: python trie levenshtein-distance

我是数据结构的新手,我正在实现一个使用编辑距离消除名称数据库歧义的特里。我正在使用以下trie实现:

http://stevehanov.ca/blog/index.php?id=114

基本上是:

class TrieNode:

    def __init__(self):
       self.word = None
       self.children = {}

       global NodeCount
       NodeCount += 1

    def insert( self, word ):
       node = self
       for letter in word:
            if letter not in node.children: 
                node.children[letter] = TrieNode()

            node = node.children[letter]

       node.word = word

# read dictionary file into a trie
trie = TrieNode()
for name in names:
    WordCount += 1
    trie.insert( name )

这样可以很好地完成工作,因为它将所有名称都插入到trie中。现在,我逐个查看名称列表,并使用trie返回与传递的名称相距特定编辑距离的所有名称的列表。我想删除列表中返回的trie中的所有名称。

有快速的方法吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

有两种方法可以执行此操作,具体取决于您是否要检查是否要删除通过任何内部节点的最后一条路径(这会使删除速度稍慢,但可能会在删除后略微加快搜索速度)。这两种方式都是递归的,但是如果你想迭代地展开它(就像你的insert那样),那么检查就不那么容易了,所以我会这样做。

def delete(self, word):
    node = self
    for letter in word[:-1]:
        if letter not in node.children:
            return False
        node = node.children[letter]
    if word[-1] in node.children:
        del node.children[letter]
        return True
    return False

你能加快速度吗?是的,但可能无关紧要。

首先,您知道节点将始终存在,因此您可以删除一些错误检查。更重要的是,如果你可以让搜索功能返回节点,而不仅仅是它们的值,这将使事情变得更快。如果您可以在trie中添加反向链接,这意味着您可以在恒定时间内擦除节点,而不是重复搜索。如果你不想反向链接,你可以通过返回拉链而不是节点来获得完全相同的好处 - 或者更简单地说,只返回一堆节点。

但实际上,这里最糟糕的情况是工作量增加一倍,而不是增加算法复杂度或乘以一个大因子,这么简单可能会胜出。