最近剛好有群友問到關於敏感詞過濾的問題,當時有人給出了一些辦法。
1. 利用hashset,對傳多來的字串進行比較。或者將敏感詞儲存到資料庫或者其他地方,然後和傳入的詞做匹配。
2. 正規表示式匹配。
上述兩個方法不用想肯定都是很慢的。後來有人說道可以利用dfa演算法,因此我去研究了一下,增加自己的知識面。
具體的解釋不在寫了,本質上是乙個狀態機,根據state+event --> nextstate。了解過工作流的人肯定不陌生狀態機這個概念的。圍繞這個狀態機,可以根據輸入的乙個詞,推導出下乙個詞是什麼。
根據參考部落格,稍微修改了下實現,本質一樣。
public class check else
if(i == key.length() - 1)}}
}/**
* 版本一
* @param txt 需要查詢的字串
* @param beginindex 查詢開始位置
* @return
*/public static setgetsensitivewordv1(string txt,int beginindex)
}else
}return str;
}}
getsensitivewordv1這個稱作版本一,和部落格裡是一樣的,但是我執行時發現一點問題。
問題一:
假設現在敏感詞是「中國人」,「你們」, 待檢測欄位是「你好啊中國人你們」,會發現只能檢測出「中國人」,而「你們」卻漏掉了,主要原因就是當讀取到「你」這個字時,發現map此時為null了,那麼原本從「中」字開始時發現此時應該是檢測敏感詞了,但是檢測到「你」時,發現不符合敏感詞規則,所以檢測出敏感詞是「中國人」,但是下一次迴圈就從「們」開始了,「你」這個字就華麗麗的溜掉了。
其實這個場景的本質就是兩個敏感詞聯在一起,導致原本檢測第乙個敏感詞時,本來該結束的時候,下乙個字時另乙個敏感詞的開始,被忽略了。
修復**:
/**
* 版本二
* @param txt 需要查詢的字串
* @param beginindex 查詢開始位置
* @return
*/public static setgetsensitivewordv2(string txt,int beginindex)
}else
//如果查詢不到,將初始值賦值給map
nowmap = localmap;
//清除當前儲存的敏感詞,可能儲存到一半發現不滿足要求,需要清空,以便下次儲存
sb.setlength(0);}}
return str;
}
但是寫著我又發現問題二了:
問題二:
假設現在敏感詞是「中國人民」,「測試」,只能檢測出「中國人民」和「測試」這兩個詞,但是如果現在有敏感詞有「中國人」的話,就檢測不出「中國人民」了,這個怎麼解決,我暫時還沒想好,只能想到針對這種情況的話,dfa應該是沒法滿足的,因為它是狀態機,「中國人」和「中國人民」在狀態機裡,原本是「民」是最後乙個狀態,但是現在「人」變成最後乙個狀態了,導致只能檢測到「中國人」就結束了,「民」就丟掉了。
前端 DFA 敏感詞過濾
最近在做遊戲的聊天功能,需要在客戶端接入敏感詞過濾,較低成本的實現方法有字典匹配和正規表示式匹配,但效率上較低。大致 google 了一遍,發現dfa演算法是實現敏感詞過濾效率較高的選擇,下面是具體實現過程。dfa演算法,即deterministic finite automaton,中文翻譯是有窮...
Java實現DFA演算法實現敏感詞過濾
在實現文字過濾的演算法中,dfa是唯一比較好的實現演算法。dfa即deterministic finite automaton,也就是確定有窮自動機,它是是通過event和當前的state得到下乙個state,即event state nextstate。下圖展示了其狀態的轉換 在這幅圖中大寫字母 ...
遊戲中敏感詞的過濾之DFA演算法
對於乙個遊戲,如果有聊天功能,那麼我們就會希望我們的聊天系統能夠對玩家的輸入進行判斷,如果玩家的輸入中含有一些敏感詞彙,那麼我們就禁止玩家傳送聊天,或者把敏感詞轉換為 來替換。設我們已經有了乙個敏感詞詞庫 從相關部門獲取到的,或者網上找來的 那麼我們最容易想到的過濾敏感詞的方法就是 遍歷整個敏感詞庫...