国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

js實現敏感詞過濾算法及實現邏輯

2019-11-19 13:25:43
字體:
來源:轉載
供稿:網友

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

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

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

DFA算法介紹

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

參考文章 Java實現敏感詞過濾

實現邏輯

構造數據結構

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

 

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

 

判斷邏輯

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

代碼實現

####構造數據結構

/*** @description* 構造敏感詞map* @private* @returns*/private makeSensitiveMap(sensitiveWordList) { // 構造根節點 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)) {    // 獲取下一層節點    map = map.get(char);   } else {    // 將當前節點設置為非結尾節點    if (map.get('laster') === true) {     map.set('laster', false);    }    const item = new Map();    // 新增節點默認為結尾節點    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: '' }; // 過濾掉除了中文、英文、數字之外的 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做比較

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

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

 

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

總結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吴桥县| 阿坝| 墨脱县| 通榆县| 高邮市| 香格里拉县| 法库县| 孟州市| 滕州市| 巴南区| 博野县| 大邑县| 沈丘县| 怀远县| 苏尼特左旗| 海宁市| 邯郸市| 金坛市| 乐都县| 汕头市| 旅游| 天台县| 钦州市| 游戏| 江都市| 岳西县| 临安市| 桃江县| 马关县| 且末县| 元朗区| 台南市| 慈利县| 河西区| 阜康市| 伊川县| 丁青县| 澄城县| 镇坪县| 资阳市| 青海省|