最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js實現(xiàn)敏感詞過濾算法及實現(xiàn)邏輯

 更新時間:2018年07月24日 11:28:02   作者:小黎也  
這篇文章主要介紹了js實現(xiàn)敏感詞過濾算法及實現(xiàn)邏輯,文中介紹了dfa算法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下

最近弄了一個用戶發(fā)表評論的功能,用戶上傳了評論,再文章下可以看到自己的評論,但作為社會主義接班人,踐行社會主義核心價值觀,所以給評論敏感詞過濾的功能不可少,在網(wǎng)上找了資料,發(fā)現(xiàn)已經有非常成熟的解決方案。 常用的方案用這么兩種

1.全文搜索,逐個匹配。這種聽起來就不夠高大上,在數(shù)據(jù)量大的情況下,會有效率問題,文末有比較

2.DFA算法-確定有限狀態(tài)自動機 附上百科鏈接確定有限狀態(tài)自動機

DFA算法介紹

DFA是一種計算模型,數(shù)據(jù)源是一個有限個集合,通過當前狀態(tài)和事件來確定下一個狀態(tài),即 狀態(tài)+事件=下一狀態(tài),由此逐步構建一個有向圖,其中的節(jié)點就是狀態(tài),所以在DFA算法中只有查找和判斷,沒有復雜的計算,從而提高算法效率

參考文章 Java實現(xiàn)敏感詞過濾

實現(xiàn)邏輯

構造數(shù)據(jù)結構

將敏感詞轉換成樹結構,舉例敏感詞有著這么幾個 ['日本鬼子','日本人','日本男人'] ,那么數(shù)據(jù)結構如下(圖片引用參考文章)

 

每個文字是一個節(jié)點,連續(xù)的節(jié)點組成一個詞, 日本人 對應的就是中間的那條鏈,我們可以使用對象或者map來構建樹,這里的栗子采用 map 構建節(jié)點,每個節(jié)點中有個狀態(tài)標識,用來表示當前節(jié)點是不是最后一個,每條鏈路必須要有個終點節(jié)點,先來看下構建節(jié)點的流程圖

 

判斷邏輯

先從文本的第一個字開始檢查,比如 你我是日本鬼子 ,第一個字 你 ,在樹的第一層找不到這個節(jié)點,那么繼續(xù)找第二個字,到了 日 的時候,第一層節(jié)點找到了,那么接著下一層節(jié)點中查找 本 ,同時判斷這個節(jié)點是不是結尾節(jié)點,若是結尾節(jié)點,則匹配成功了,反之繼續(xù)匹配

代碼實現(xiàn)

####構造數(shù)據(jù)結構

/**
* @description
* 構造敏感詞map
* @private
* @returns
*/
private makeSensitiveMap(sensitiveWordList) {
 // 構造根節(jié)點
 const result = new Map();
 for (const word of sensitiveWordList) {
  let map = result;
  for (let i = 0; i < word.length; i++) {
   // 依次獲取字
   const char = word.charAt(i);
   // 判斷是否存在
   if (map.get(char)) {
    // 獲取下一層節(jié)點
    map = map.get(char);
   } else {
    // 將當前節(jié)點設置為非結尾節(jié)點
    if (map.get('laster') === true) {
     map.set('laster', false);
    }
    const item = new Map();
    // 新增節(jié)點默認為結尾節(jié)點
    item.set('laster', true);
    map.set(char, item);
    map = map.get(char);
   }
  }

 }
 return result;
}

最終map結構如下

 

查找敏感詞

/**
* @description
* 檢查敏感詞是否存在
* @private
* @param {any} txt
* @param {any} index
* @returns
*/
private checkSensitiveWord(sensitiveMap, txt, index) {
 let currentMap = sensitiveMap;
 let flag = false;
 let wordNum = 0;//記錄過濾
 let sensitiveWord = ''; //記錄過濾出來的敏感詞
 for (let i = index; i < txt.length; i++) {
  const word = txt.charAt(i);
  currentMap = currentMap.get(word);
  if (currentMap) {
   wordNum++;
   sensitiveWord += word;
   if (currentMap.get('laster') === true) {
    // 表示已到詞的結尾
    flag = true;
    break;
   }
  } else {
   break;
  }
 }
 // 兩字成詞
 if (wordNum < 2) {
  flag = false;
 }
 return { flag, sensitiveWord };
}
/**
* @description
* 判斷文本中是否存在敏感詞
* @param {any} txt
* @returns
*/
public filterSensitiveWord(txt, sensitiveMap) {
 let matchResult = { flag: false, sensitiveWord: '' };
 // 過濾掉除了中文、英文、數(shù)字之外的
 const txtTrim = txt.replace(/[^\u4e00-\u9fa5\u0030-\u0039\u0061-\u007a\u0041-\u005a]+/g, '');
 for (let i = 0; i < txtTrim.length; i++) {
  matchResult = checkSensitiveWord(sensitiveMap, txtTrim, i);
  if (matchResult.flag) {
   console.log(`sensitiveWord:${matchResult.sensitiveWord}`);
   break;
  }
 }
 return matchResult;
}

效率

為了看出DFA的效率,我做了個簡單的小測試,測試的文本長度為5095個漢字,敏感詞詞庫中有2000個敏感詞,比較的算法分別為 DFA算法 和 String原生對象提供的 indexOf API做比較

// 簡單的字符串匹配-indexOf
ensitiveWords.forEach((word) => {
 if (ss.indexOf(word) !== -1) {
  console.log(word)
 }
})

分別將兩個算法執(zhí)行100次,得到如下結果

 

可直觀看出, DFA 的平均耗時是在1ms左右,最大為5ms; indexOf 方式的平均耗時在9ms左右,最大為14ms,所以DFA效率上還是非常明顯有優(yōu)勢的。

總結

以上所述是小編給大家介紹的js實現(xiàn)敏感詞過濾算法及實現(xiàn)邏輯,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

最新評論

泊头市| 门头沟区| 伊春市| 鸡泽县| 廊坊市| 岗巴县| 固原市| 深泽县| 阳新县| 济阳县| 高尔夫| 马山县| 文安县| 丹巴县| 广南县| 沙田区| 晋江市| 墨江| 南和县| 镇原县| 玉屏| 四子王旗| 灵山县| 临朐县| 梁河县| 芜湖市| 饶平县| 永定县| 吉首市| 长垣县| 万山特区| 宣武区| 三江| 宿松县| 尚志市| 牙克石市| 安溪县| 洪江市| 平罗县| 靖边县| 和田市|