雙陣列TRIE樹Double-Array Trie理解引導

明天,今天,此時發表於2020-11-25

啟文

	很難懂很難懂
	不知道什麼時候開始,看別人的寫的東西都看不懂了,不知道是自己思維出現問題,還是別人的表達確實存在歧義。一個點存在一個歧義,兩個點歧義就變成4種理解,3點、4點還得了。一點存在歧義就沒得辦法看懂。

double Array trie的實現不過很多年沒更新,似乎都不能下載了,裡面談到幾次論文更新:

  1. Tripple-Array Trie
  2. Double-Array Trie
  3. Suffix Compression-> double-array branches and suffix-spool tail
  4. Double-Array Pool Allocation->G-link

換句話說效果比較好的就是這個DATrie的G-link方法,效果更好的裡面沒提起,不解釋了。

https://linux.thai.net/~thep/datrie/datrie.html這裡面介紹了double-array-trie的方法演進,很久沒更新了不知道有新的改進沒。

https://zhuanlan.zhihu.com/p/185832624這裡漢語版理解double-array-trie的過程,百度百科不用看了看不懂的,就看他的吧!

https://blog.csdn.net/zzran/article/details/8462002 是前面的第3點改進double-array-trie的做法,就是字尾

G-link還沒理解

先理解double-array-trie計算過程,只是計算過程看通了,原理沒懂,還得繼續瞭解。

先構建

詞集:【a,ab,bbc,bc】

根據詞集生成語料:
字符集:【a,b,c】
狀態集:【a,ab,b,bb,bc,bbc】

計算流程是這樣的(python的格式,雖然是兩陣列其實還有其他變數參與):
初始化:

字符集建立字典:index={a:1,b:2,c:3} #舉例index[c]=3
狀態集也建立字典:state={none:0,a:none,ab:none,b:none,bb:none,bc:none,bbc:none} #none是空,這個字典記錄的狀態的過程狀態值,起始時除了none鍵,其它沒定義值;
定義陣列:base=[0,none,none,none,none,none,none,none] #總共8個元素為啥?比狀態多吧
定義陣列:check=[none,none,none,none,none,none,none,none] #個數和base一樣
`base`是字串去掉最後一個字元剩下的字串。

建立公式如下:
在這裡插入圖片描述

  • 初始化
    在這裡插入圖片描述
  • 計算字串a
    在這裡插入圖片描述
  • 計算字串ab
    在這裡插入圖片描述
  • 計算字串bbc
    bbc經過反推,bbc沒有bb的`base`,再推沒有b的`base`,所以要從b開始建立陣列值。
      計算字串b
    在這裡插入圖片描述
      計算字串bb
    在這裡插入圖片描述
      計算字串bbc
    在這裡插入圖片描述
  • 計算字串bc
    在這裡插入圖片描述
    到此為止構建完成了,構建過程很容易理解,為什麼這麼構建?還要進一步分析。

查詢

驗證公式如下
在這裡插入圖片描述
查詢ab
  先查a再查詢ab
在這裡插入圖片描述
ab配對成功。
接下來匹配abc,上接ab查詢:
在這裡插入圖片描述
匹配失敗。

結語

  state中的值不能重複,其值對應base陣列中的索引,理解為“佔索引”,base陣列和check陣列的索引是一一對應的。

  trie數對英文特別好,因為英文就26個字母,漢字就不同了幾千到幾萬個常用字元,所以用double-array trie,構建後查詢特別快。還必須瞭解的FST共享字首樹,這是lucene用的結構需要了解一下。

  這些結構涉及到前沿技術,必須懂!

另:1)前面的計算過程是仿照前面給出的連線中的文章演示翻譯出來的還沒進行驗證;2)這個計算過程為什麼這麼計算還沒弄透,搞透後更新這篇部落格。

  後面更新這兩點,或者理解的朋友留言告知,你不說我不說,就沒有網際網路共享的知識,分享還能幫助記憶嗎沒錯吧。

相關文章