簡體   English   中英

Python中的Trie(前綴樹)

[英]Trie (Prefix Tree) in Python

我不知道這是否是詢問算法的地方。 但是,讓我們看看我是否得到任何答案...... :)

如果有什么不清楚我很樂意澄清事情。

我剛剛在python中實現了一個Trie 然而,有一點似乎比它應該更復雜(作為一個喜歡簡單的人)。 也許有人遇到過類似的問題?

我的目標是通過在其根中存儲子trie的最大公共前綴來最小化節點數。 例如,如果我們有stackoverflowstackbasestackbased這兩個詞,那么樹看起來像這樣:

              [s]tack
[o]verflow ______/ \_______ [b]ase
                                  \___ [d]

注意,人們仍然可以想到邊緣具有一個字符(子節點的第一個)。

查找 -query很容易實現。 插入並不難,但比我想要的更復雜.. :(

我的想法是一個接一個地插入密鑰(從一個空的trie開始),首先搜索要插入的密鑰k( Find (k)),然后在本地重新排列/拆分節點查找程序停止。 結果是4種情況:(設k是我們要插入的鍵,k'是節點的關鍵,搜索結束)

  1. k與k'相同
  2. k是k'的“正確”前綴
  3. k'是k的“正確”前綴
  4. k和k'共享一些共同的前綴,但沒有一種情況發生(1),(2)或(3)。

似乎每個案例都是獨特的,因此意味着對Trie的不同修改。 但是:真的那么復雜嗎? 我錯過了什么嗎? 有更好的方法嗎?

謝謝 :)

乍一看,聽起來你已經實現了Patricia Trie 在一些文獻中,這種方法也稱為路徑壓縮。 應該有不在ACM付費專區后面的那篇論文的副本,其中將包括插入算法。

您還可以查看另一種壓縮方法:級別壓縮。 路徑壓縮背后的想法是用一個具有“跳過”計數的超級節點替換單個子節點的字符串。 級別壓縮背后的想法是用超級節點替換完整或接近完整的子樹,其中“度”計數表示節點解碼的密鑰的位數。 還有一種稱為寬度壓縮的第三種方法,但我擔心我的記憶失敗了,我無法通過快速谷歌搜索找到它的描述。

級別壓縮可以顯着縮短平均路徑,但插入和刪除算法變得非常復雜,因為它們需要像動態數組一樣管理trie節點。 對於正確的數據集,級別壓縮樹可以很快 根據我的記憶,它們是存儲IP路由表的第二快方法,最快的是某種哈希特里。

我認為你的方法沒有任何問題。 如果你正在尋找尖峰解決方案,也許在案例4中采取的行動對於前三種情況實際上是可行的,IE找到kk'的公共前綴並重建節點時考慮到這一點。 如果碰巧鍵是彼此的前綴,那么生成的trie仍然是正確的,只有實現做了比實際更多的工作。 但話又說回來,沒有任何代碼可以看,很難說這是否適合你的情況。

有些切線,但如果你對Trie中的節點數量非常擔心,你可能會考慮加入你的單詞后綴。 我將看一下DAWG(Directed Acyclic Word Graph)的想法: http//en.wikipedia.org/wiki/Directed_acyclic_word_graph

這些的缺點是它們不是很動態,創建它們可能很困難。 但是,如果你的字典是靜態的,它們可以超級緊湊。

我對您的實施有疑問。 您決定將字符串拆分為前綴樹的粒度級別是多少。 您可以將堆棧拆分為s,t,a,c,k或st,ta,ac,ck以及其他許多ngrams。 大多數前綴樹實現都會考慮語言的字母表,基於此字母表,您可以進行拆分。

如果你正在構建python的前綴樹實現,那么你的字母表將是def,:,if,else等等

選擇正確的字母表會對構建高效的前綴樹產生巨大的影響。 至於你的答案,你可以在CPAN上尋找使用trie進行最長公共子串計算的PERL包。 你可能會有一些運氣,因為他們的大多數實現非常強大。

請看:Judy-arrays和http://www.dalkescientific.com/Python/PyJudy.html上的python接口

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM