Trie 樹 搜尋關鍵詞提示

2021-09-24 07:53:55 字數 2656 閱讀 6513

trie 樹也叫 「字典樹」。顧名思義,它是乙個樹形結構,專門用來處理在一組字串集合中快速查詢某個字串的問題。

假設我們有 6 個字串,它們分別是:how,hi,her,hello,so,see。我們希望在這裡面多次查詢某個字串是否存在,如果每次都拿要查詢的字串和這六個字串依次進行匹配,那效率就會比較低。

如果我們可以對這六個字串做一下預處理,組織成 trie 樹的結構,那之後每次查詢,都只要在 trie 樹中進行匹配即可。trie 樹的本質,就是利用字串之間的公共字首,將重複的字首合併在一起

其中,根節點不包含任何資訊,每個節點代表字串中的乙個字元,從根節點到紅色節點的一條路徑表示乙個字串。注意紅色節點並不都是葉子節點,比如有兩個詞 how 和 however,那麼 w 和 r 都是紅色節點。乙個 trie 樹的構造過程如下所示。

當我們要在構建好的 trie 樹中查詢乙個字串的時候,那就要將查詢的字串分割成單個的字元,然後從根節點開始匹配。如下面的例子所示,綠色路徑就是 「her」 的匹配路徑,而 「he」 的最後乙個匹配節點並不是紅色節點,所以其並不能完全匹配任何字串。

從上面我們可以看到,trie 樹主要有兩個操作:乙個是將字串集合構建成 trie 樹,另乙個是在 trie 樹中查詢乙個字串

trie 樹是乙個多叉樹結構,其子節點個數事先未知,但我們可以借助雜湊表的思想,在下標與字元之間建立乙個一一對映,來儲存子節點的指標。

假設我們的字串只有 a 到 z 這 26 個字母,那麼陣列下標為 0 的元素就儲存指向子節點 a 的指標,下標為 1 的元素就儲存指向子節點 b 的指標,以此類推,下標為 25 的元素就儲存指向子節點 z 的指標。如果某個字元的子節點不存在,那對應該下標位置的元素就為 null。當我們在 trie 樹中進行查詢的時候,就可以拿字元的 ascii 碼減去 'a' 的 ascii 碼來獲取其子節點的指標。

#include

#include

using

namespace

std;

class

trienode

};class

trie

// 向 trie 樹中新增乙個字串

void

insert_string

(const

char str)

cur = cur->children[index];

}cur->is_ending_char = true;

}// 在 trie 樹中查詢乙個字串

bool

search_string

(const

char str)

cur = cur->children[index];

}if (cur->is_ending_char == true) return

true;

else

return

false;

}};int

main();

trie test;

for (int i = 0; i < 7; i++)

cout

<< "finding \'her\': "

<< test.search_string("her") << endl;

cout

<< "finding \'he\': "

<< test.search_string("he") << endl;

cout

<< "finding \'how\': "

<< test.search_string("how") << endl;

cout

<< "finding \'however\': "

<< test.search_string("however") << endl;

return0;}

複製**

在構建 trie 樹的過程中,需要掃瞄所有的字串,時間複雜度為 o(n),其中 n 表示所有字串的長度之和。而在 trie 樹中進行查詢的話,如果待查詢字串的長度為 k 的話,那最多隻需要對比 k 個節點即可,時間複雜度為 o(k)。

在上面的例子中,trie 樹的每個節點都要儲存 26 個指標,儘管某些節點的子節點很少,我們依然要維護這麼乙個長度的陣列。另外,如果字串中不僅包含小寫字母,而且包含大寫字母、數字甚至是中文等,那就會需要更多的儲存空間。也就是說,在某些情況下,trie 樹並不一定會節省記憶體空間,尤其是在重複字首不多的時候。

當然,儘管 trie 樹可能會很浪費記憶體,但是確實非常高效,這也是一種空間換時間的折中。如果我們可以稍微犧牲一點查詢的效率,那就可以選用陣列、雜湊表、紅黑樹等其他資料結構來儲存乙個節點的子節點指標。

假設我們使用陣列,陣列中的指標按照所指向子節點的字元大小順序排列。這樣,在查詢的時候,我們可以通過二分演算法來快速找到指向子節點的指標。但是,在往 trie 樹中插入字串的話,為了維護陣列的有序性,就會稍微慢了點。

另外,還可以採用縮點優化,將只有乙個子節點而且不是結束節點的節點與其子節點進行合併,來節省空間,但這也增加了編碼難度。

在字串匹配或者說查詢問題上,trie 樹對要處理的字串有極其嚴格的要求。

另外,trie 樹還可以擴充套件到更加廣泛的應用上,比如輸入法、**編輯器和瀏覽器的自動輸入補全功能。

參考資料-極客時間專欄《資料結構與演算法之美》

Trie樹 實現搜尋引擎的搜尋關鍵詞提示功能

快速查詢某個字串的功能。比如,我們有6個字串,它們分別是 how,hi,her,hello,so,see。我們希望在裡面多次查詢某個字元是否存在。我們可以先對這6個字串做一下預處理,組織成trie樹的結構,之後每次查詢,都是在trie樹中進行匹配查詢。trie樹的本質,就是利用字串之間的公共字首,將...

nlp 關鍵詞搜尋

可以嘗試修改 除錯 公升級的部分是 文字預處理步驟 你可以使用很多不同的方法來使得文字資料變得更加清潔 更好的回歸模型 根據之前的課講的ensemble方法,把分類器提公升到極致 版本1.0 日期 10.10.2019 import numpy as np import pandas as pd f...

關鍵詞搜尋結果頁看關鍵詞競爭大小

大家好,我是虛子雨。最近有好幾個朋友問到我怎麼看關鍵詞的競爭大小,我才發現其實很多的人對於關鍵詞的競爭大小很關注的。這不僅僅是我們站長需要弄懂的乙個小的知識點,也是很多企業主應該弄懂的。對於站長來說我們做優化需要弄懂關鍵詞競爭大小,在給這些關鍵詞作分析選擇的時候會用到,在優化的過程中也會用到,在分析...