1【背景】
這個在網路上也叫「敏感詞過濾」,比如一些論壇、貼吧,涉及政治類詞、罵爹罵娘的詞,就得過濾掉。
我是閒著無聊,就看了下。
一開始想著用好幾個replace不就好了嗎,後來網上說這種效率太低了。
查了下,發現這一塊還是比較深,最後我找了2種方法(方法是別人寫的,從網上找的),都是精確匹配髒詞的。效率如何不怎麼關心,反正是有點意思的,所以想發一下。
(精確匹配髒詞)這種方法得有個髒詞庫,目的就是將x文字出現的髒詞替換掉。(還有人推薦了一種用貝葉斯公式替換髒詞的,這種是靠概率,不是精確替換。有興趣的可以了解下)
2.1叫它byte方法,也不知道有沒有名字。**裡面對應——badwordsfilter。
該演算法的亮點是fastcheck,它代表某個髒字,在所有髒詞裡,曾出現的位置,比較機巧。因為它是位置資訊,在檢測髒詞的時候有優勢,可以減少判斷。2.2tire(字首樹)方法缺點是fastcheck裡有很多無用位置,並且因為它是byte,導致髒詞長度最多只能有8位。
因為這些缺點,我試著改了下——badwordsfilter2。改了以後好像變慢了許多。
還有就是這個方法簡單、好寫。比上乙個方法要好寫。
3【結果評價】
哪個方法更好就不說了,實現的東西都不同,沒有可比性。
但是為什麼我的badwordsfilter2會比原版的慢那麼多?乙個是4.0001ms,乙個是1.0001ms。
從我開始寫**,就不怎麼會測效率問題。還是機巧的方法更能激起我的興趣。
這種byte表示位的思想,以前有遇到過,比如:5個數里取3個。可以寫成單迴圈(2^6-1次),像10110,有3個1的就可以取。
4【**】
using system;
using system.collections.generic;
using system.collections;
; var text = @"手機版| 敏感詞收藏本站
**首頁
政務公開
網上辦事
互動交流
專題專欄
幫助中心
我要諮詢
常見問題
站點地圖
手機門戶
評比統計
導航鏈結
#region 叉樹演算法部分
trie trie = new trie();
foreach (string keyword in keywords) trie.add(keyword);
int size = 0;
int researchcount = 0;//總共搜尋到的次數
size += text.length;
string foundkeyword = null;
for (int i = 0; i < text.length ; i++)
if (token == null) break;}}
datetime dt2 = datetime.now;
timespan ts = dt2 - dt1;
console.writeline(ts.totalmilliseconds + "ms 總共搜尋字元數" + size + " 搜尋整文出現的次數為:" + researchcount);
#endregion 叉樹演算法部分
#region byte演算法
dt1 = datetime.now;
badwordsfilter wfilter = new badwordsfilter();
foreach (string keyword in keywords) wfilter.addkey(keyword);
string str1 = wfilter.replacebadword(text);
dt2 = datetime.now;
console.writeline((dt2 - dt1).totalmilliseconds + "ms (byte演算法)");
#endregion
#region byte2演算法
dt1 = datetime.now;
badwordsfilter2 bwfilter = new badwordsfilter2();
foreach (string keyword in keywords) bwfilter.addkey(keyword);
string str2 = bwfilter.replacebadword(text);
dt2 = datetime.now;
console.writeline((dt2 - dt1).totalmilliseconds + "ms (byte2演算法)");
#endregion
console.readline();}}
//字首樹 結構
public class trie
public void add(string word)
node.addchild((char)0);
}public void delete(string word)
node.deletechild((char)0);
}public bool exist(string word)
return node.getchild((char)0) != null;
}public bool exist(char c, ref object token)
class trienode
public bool haschild()
public trienode getchild(char c)
public trienode addchild(char c)
return node;
}public bool deletechild(char c)
return bol;
}public bool terminated }}}
//這個是網上抄的,寫法比較經典
public class badwordsfilter
if (word.length == 1)
else
}/// /// 髒詞替換
///
///
///
public string replacebadword(string text)
//單位元組檢測
if (minwordlength == 1 && charcheck[text[index]])
//多位元組檢測
for (int j = 1; j <= math.min(maxwordlength, text.length - index - 1); j++)}}
}return text;}}
//這個是根據badwordsfilter改的
public class badwordsfilter2
/// /// 髒詞替換
///
///
///
public string replacebadword(string text)
//多字元
for (int j = 1; j <= math.min(maxwordlength, text.length - index - 1); j++)}}
}return text;}}
}
5【結果】
Trie樹 髒詞過濾應用
當前的 還只是進行簡單的替換,並沒有做一些字元的處理,比如 昨天見到你媽,逼我要買房 這本身不是髒詞,因為有逗號,所以程式裡要增加字元的範圍判斷。程式中的skip就是用來過濾髒詞的簡單變體,比如 找 小 姐 預設是最多跳過3個字元,這個可以隨便調整了。總之是乙個trie的鍛鍊吧。public cla...
通過redis協議構建中文髒詞過濾微服務
mkdir p data server wordsfilter cd data server wordsfilter wget o gorediswordsfilter v0.0 1.tar gz 1.tar gz tar zxvf gorediswordsfilter v0.0 1.tar gzc...
敏感詞過濾
最近需要實現對聊天裡的敏感詞過濾,要求比較簡單,只需要對字型檔中存在的關鍵字進行匹配,所以不需要非常複雜的實現,但是需要能夠快速地對乙個關鍵字集合進行匹配。搜了一下相關的資料,比較簡單的乙個演算法是使用aho corasick演算法,以下簡稱ac演算法。該演算法的基本思想中包含了kmp演算法,即利用...