Trie樹,加快單詞查詢效率
阿新 • • 發佈:2018-12-19
為了提高我的單詞查詢的速度,我拜讀了@Rshcaroline的程式碼,發現trie樹是一個很好解決這個問題的方法
Trie樹,又叫字典樹、字首樹(Prefix Tree)、單詞查詢樹 或 鍵樹,是一種多叉樹結構
Trie樹的基本性質:
- 根節點不包含字元,除根節點外的每一個子節點都包含一個字元。
- 從根節點到某一個節點,路徑上經過的字元連線起來,為該節點對應的字串。
- 每個節點的所有子節點包含的字元互不相同。 通常在實現的時候,會在節點結構中設定一個標誌,用來標記該結點處是否構成一個單詞(關鍵字)。
一下是我的程式碼
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = {}
self.END = "$"
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
t = self.root
for c in word:
if c not in t:
t[c] = {}
t = t[c]
t[self.END] = {}
def search(self, word):
"""1
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
t = self.root
for c in word:
if c not in t:
return False
else :
t = t[c]
if self.END not in t:
return False
return True
def startsWith(self, prefix):
"""
Returns if there is any word in the trie that starts with the given prefix.
:type prefix: str
:rtype: bool
"""
t = self.root
for c in prefix:
if c not in t:
return False
else:
t = t[c]
return True
對於一個單詞的查詢一定編輯距離的相關集合的程式碼如下(from @Rshcaroline),其中的deque是python的高效能雙向佇列,用於將trie, word, path, edit_distance整個打包起來加入佇列, 廣度優先查詢符合的單詞
def get_candidate(trie, word, edit_distance=1):
que = deque([(trie, word, '', edit_distance)])
while que:
trie, word, path, edit_distance = que.popleft()
if word == '':
if END in trie:
yield path
# 詞尾增加字母
if edit_distance > 0:
for k in trie:
if k != END:
que.appendleft((trie[k], '', path+k, edit_distance-1))
else:
if word[0] in trie:
# 首字母匹配成功
que.appendleft((trie[word[0]], word[1:], path+word[0], edit_distance))
# 無論首字母是否匹配成功,都如下處理
if edit_distance > 0:
edit_distance -= 1
for k in trie.keys() - {word[0], END}:
# 用k替換餘詞首字母,進入trie[k]
que.append((trie[k], word[1:], path+k, edit_distance))
# 用k作為增加的首字母,進入trie[k]
que.append((trie[k], word, path+k, edit_distance))
# 刪除目標詞首字母,保持所處結點位置trie
que.append((trie, word[1:], path, edit_distance))
# 交換目標詞前兩個字母,保持所處結點位置trie
if len(word) > 1:
que.append((trie, word[1]+word[0]+word[2:], path, edit_distance))