trie樹 單詞樹 實現敏感詞遮蔽和詞頻統計

2021-10-01 10:30:47 字數 3473 閱讀 4055

三、**實現

前幾天都看乙個敏感詞遮蔽演算法的文章,寫的挺好,順著思路寫了下去,實現了一下,演算法效率還是槓槓的。。。

利用的是單詞樹的演算法,先看看什麼叫單詞樹。單詞樹也叫trie 樹也稱為字典樹。最大的特點就是共享字串的公共字首來達到節省空間的目的。

例如,字串 "abc"和"abd"構成的單詞樹如下:

樹的根節點不存任何資料,每整個個分支代表乙個完整的字串。像 abc 和 abd 有公共字首 ab,所以我們可以共享節點 ab。如果再插入 abf,則變成這樣:

這樣看來能實現的功能就很顯而易見了,例如詞頻統計,單詞查詢,還有就是遊戲裡的敏感詞遮蔽。

來具體說說實現的思路吧。

這兩個都是同一種思路。即下面**裡的find_word_exists函式,詞頻統計加個累計就好了。

關鍵在建立單詞樹的時候,需要新增子節點,另外還要標記單詞是否在此處是完整單詞。然後將乙個個字元插入即可。

這個稍微複雜點。即下面**裡的sensitive_word_filter函式。

需要三個指標來遍歷實現,兩個在檢查的單詞上,乙個在單詞樹上。

1、首先指標 p1 指向 root,指標 p2 和 p3 指向字串第乙個字元

2、然後從字串的 a 開始,檢測有沒有以 a 作為字首的敏感詞,直接判斷 p1 的孩子節點中是否有 a 這個節點就可以了,顯然這裡沒有。接著把指標 p2 和 p3 向右移動一格。

3、然後從字串 b 開始查詢,看看是否有以 b 作為字首的字串,p1 的孩子節點中有 b,這時,我們把 p1 指向節點 b,p2 向右移動一格,不過,p3不動。

4、判斷 p1 的孩子節點中是否存在 p2 指向的字元c,顯然有。我們把 p1 指向節點 c,p2 向右移動一格,p3不動。

5、判斷 p1 的孩子節點中是否存在 p2 指向的字元d,這裡沒有。這意味著,不存在以字元b作為字首的敏感詞。這時我們把p2和p3都移向字元c,p1 還是還原到最開始指向 root。

6、和前面的步驟一樣,判斷有沒以 c 作為字首的字串,顯然這裡沒有,所以把 p2 和 p3 移到字元 d。

到這裡應該差不多懂了。。。後面都一樣。那開始動手實踐。

這裡的詞頻統計,單詞查詢和敏感詞遮蔽都實現了,如下;

#include #include using namespace std;

#pragma pack(1)

struct trie_node

}};#pragma pack()

class trie

~trie()

trie_node* create()

void insert(const char* str)

trie_node* next_node = _root_node;

while(*str != 0)

else

next_node = next_node->childs[index];

next_node->letter = *str;

str++;

}next_node->is_terminal = true;

}bool find_word_exists(const char* str)

trie_node* cur_node = _root_node;

dostr++;

}while (*str != 0);

return cur_node->is_terminal; /* 直接看當前是否有完整單詞的標誌 */

}void sensitive_word_filter(char* str)

char* pre = str;

char* cur = str;

trie_node* cur_node = _root_node;

do*pre = '*';

// 向後移動,重新開始單詞樹查詢

cur++;

pre = cur;

cur_node = _root_node;

continue;

}cur_node = cur_node->childs[index];

cur++;

}else

}while (*cur != 0);

return;

}void delete_trie(trie_node* node)

for (int i = 0; i < trie_node::letter_count; i++)

}delete node;

}};int main(int argc, char** ar**)

char* word = null;

if(null != ar**[1])

else

trie trie_tree = trie();

trie_tree.insert("back");

trie_tree.insert("backen");

trie_tree.insert("basic");

/*1. 詞頻統計,和單詞查詢*/

bool is_find = trie_tree.find_word_exists(word);

if(is_find)

else

/*2. 敏感詞遮蔽*/

trie_tree.sensitive_word_filter(word);

printf("word = %s\n", word);

return 0;

}

執行結果:

find word

word = ****

./a.out backhahaha執行結果:

not find

word = ****hahaha

Trie樹(單詞查詢樹)

前言 tire樹,又稱之為字典樹或者單詞查詢樹。是一種樹形結構,是雜湊樹的變種。典型應用是用於統計 排序或儲存大量的字串 不僅限於字串 所以經常被搜尋引擎系統用於文字詞頻的統計。因為相同的字串字首會共享同一條分支,所以優點是可以利用不同字串的相同字首來減少無謂的字串比較,查詢效率比hash表 has...

Trie 單詞查詢樹

l 簡介 trie 又稱單詞查詢樹 字首樹,是一種雜湊樹的變種。應用於字串的統計與排序,經常被搜尋引擎系統用於文字詞頻統計。含有單詞 tea tree a zsu 的一棵trie l性質 n根節點不包含字元,除根節點外的每乙個節點都只包含乙個字元。n從根節點到某一節點,路徑上經過的字元連線起來,為該...

Trie 單詞查詢樹

l 簡介 trie 又稱單詞查詢樹 字首樹,是一種雜湊樹的變種。應用於字串的統計與排序,經常被搜尋引擎系統用於文字詞頻統計。含有單詞 tea tree a zsu 的一棵trie l性質n 根節點不包含字元,除根節點外的每乙個節點都只包含乙個字元。n 從根節點到某一節點,路徑上經過的字元連線起來,為...