日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

敏感词过滤算法DFA

發(fā)布時(shí)間:2023/12/20 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 敏感词过滤算法DFA 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

DFA

敏感詞過濾方案

1 使用數(shù)據(jù)庫模糊查詢,效率太低

2 使用String.indexOf("")查找,數(shù)據(jù)庫量大的話也是比較慢

3 把敏感詞和內(nèi)容使用全文檢索(solr,ElasticSearche)技術(shù)進(jìn)行分詞再匹配,也是可以的,但是這種方案比較麻煩。

4 DFA算法,確定有窮自動(dòng)機(jī)。本項(xiàng)目采用這種方案

DFA全稱為:Deterministic Finite Automaton,即確定有窮自動(dòng)機(jī)。其特征為:有一個(gè)有限狀態(tài)集合和一些從一個(gè)狀態(tài)通向另一個(gè)狀態(tài)的邊,每條邊上標(biāo)記有一個(gè)符號(hào),其中一個(gè)狀態(tài)是初態(tài),某些狀態(tài)是終態(tài)。但不同于不確定的有限自動(dòng)機(jī),DFA中不會(huì)有從同一狀態(tài)出發(fā)的兩條邊標(biāo)志有相同的符號(hào)。

  • 一次性的把所有的敏感詞存儲(chǔ)到了多個(gè)map中,就是下圖表示這種結(jié)構(gòu)

敏感詞:冰毒、大麻、大壞蛋

  • 檢索的過程,就是hashMap的get實(shí)現(xiàn)

1、第一個(gè)字“冰”,我們?cè)趆ashMap中可以找到。得到一個(gè)新的map = hashMap.get("")。

2、如果map == null,則不是敏感詞。否則跳至3

3、獲取map中的isEnd,通過isEnd是否等于1來判斷該詞是否為最后一個(gè)。如果isEnd == 1表示該詞為敏感詞,否則跳至1。

通過這個(gè)步驟我們可以判斷“冰毒”為敏感詞,但是如果我們輸入“冰箱”則不是敏感詞了。

工具類:

import java.util.*;public class SensitiveWordUtil {public static Map<String, Object> dictionaryMap = new HashMap<>();/*** 生成關(guān)鍵詞字典庫* @param words* @return*/public static void initMap(Collection<String> words) {if (words == null) {System.out.println("敏感詞列表不能為空");return ;}// map初始長度words.size(),整個(gè)字典庫的入口字?jǐn)?shù)(小于words.size(),因?yàn)椴煌脑~可能會(huì)有相同的首字)Map<String, Object> map = new HashMap<>(words.size());// 遍歷過程中當(dāng)前層次的數(shù)據(jù)Map<String, Object> curMap = null;Iterator<String> iterator = words.iterator();while (iterator.hasNext()) {String word = iterator.next();curMap = map;int len = word.length();for (int i =0; i < len; i++) {// 遍歷每個(gè)詞的字String key = String.valueOf(word.charAt(i));// 當(dāng)前字在當(dāng)前層是否存在, 不存在則新建, 當(dāng)前層數(shù)據(jù)指向下一個(gè)節(jié)點(diǎn), 繼續(xù)判斷是否存在數(shù)據(jù)Map<String, Object> wordMap = (Map<String, Object>) curMap.get(key);if (wordMap == null) {// 每個(gè)節(jié)點(diǎn)存在兩個(gè)數(shù)據(jù): 下一個(gè)節(jié)點(diǎn)和isEnd(是否結(jié)束標(biāo)志)wordMap = new HashMap<>(2);wordMap.put("isEnd", "0");curMap.put(key, wordMap);}curMap = wordMap;// 如果當(dāng)前字是詞的最后一個(gè)字,則將isEnd標(biāo)志置1if (i == len -1) {curMap.put("isEnd", "1");}}}dictionaryMap = map;}/*** 搜索文本中某個(gè)文字是否匹配關(guān)鍵詞* @param text* @param beginIndex* @return*/private static int checkWord(String text, int beginIndex) {if (dictionaryMap == null) {throw new RuntimeException("字典不能為空");}boolean isEnd = false;int wordLength = 0;Map<String, Object> curMap = dictionaryMap;int len = text.length();// 從文本的第beginIndex開始匹配for (int i = beginIndex; i < len; i++) {String key = String.valueOf(text.charAt(i));// 獲取當(dāng)前key的下一個(gè)節(jié)點(diǎn)curMap = (Map<String, Object>) curMap.get(key);if (curMap == null) {break;} else {wordLength ++;if ("1".equals(curMap.get("isEnd"))) {isEnd = true;}}}if (!isEnd) {wordLength = 0;}return wordLength;}/*** 獲取匹配的關(guān)鍵詞和命中次數(shù)* @param text* @return*/public static Map<String, Integer> matchWords(String text) {Map<String, Integer> wordMap = new HashMap<>();int len = text.length();for (int i = 0; i < len; i++) {int wordLength = checkWord(text, i);if (wordLength > 0) {String word = text.substring(i, i + wordLength);// 添加關(guān)鍵詞匹配次數(shù)if (wordMap.containsKey(word)) {wordMap.put(word, wordMap.get(word) + 1);} else {wordMap.put(word, 1);}i += wordLength - 1;}}return wordMap;}public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("冰毒");initMap(list);String content="我是一個(gè)好人,買賣冰毒是違法的";Map<String, Integer> map = matchWords(content);System.out.println(map);} }

總結(jié)

以上是生活随笔為你收集整理的敏感词过滤算法DFA的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。