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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

敏感词过滤算法的实现

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

最近一直在做項目,突然想起來好久沒有寫過博客了,于是就有了這篇博客。這篇博客的目的就是為了在自己忘記的時候可以快速撿起來。好了,廢話不多說了,以下就是正文。

要從哪里講起呢,先講講打算怎么做吧
這個算法是采用字典樹(也就是多叉樹)來存儲敏感詞,然后通過三個指針來對文本進(jìn)行篩選,算了,我文字描述太差了,上圖花的時間太多,直接上代碼吧!

首先,需要定義一個字典樹結(jié)構(gòu)

private class TrieNode{/*** 用來存儲子節(jié)點*/private Map<Character,TrieNode> subNodes = new HashMap<>();/*** 用來表示敏感詞的終結(jié),true為終結(jié)*/private boolean end = false;/*** 設(shè)置子節(jié)點* @param key* @param node*/public void setSubNode(Character key,TrieNode node){subNodes.put(key,node);}/*** 獲取子節(jié)點* @param key* @return*/public TrieNode getSubNode(Character key){return subNodes.get(key);}/*** 設(shè)置本節(jié)點是否是敏感詞的終結(jié)* @param end*/public void setKeywordEnd(boolean end){this.end = end;}/*** 判斷是否是敏感詞的終結(jié)* @return*/public boolean isKeywordEnd(){return this.end;}/*** 獲取子節(jié)點的數(shù)量* @return*/public int getSubNodeCount(){return subNodes.size();}}

哦豁!發(fā)現(xiàn)沒有什么可以講的,都已經(jīng)注釋了,那下一個吧

對字典樹進(jìn)行初始化

@Overridepublic void afterPropertiesSet() throws Exception {InputStream is = null;InputStreamReader isr = null;BufferedReader reader = null;try {is = Thread.currentThread().getContextClassLoader().getResourceAsStream("SensitiveWords.txt");isr = new InputStreamReader(is);reader = new BufferedReader(isr);String lineTxt;while ((lineTxt = reader.readLine()) != null){lineTxt = lineTxt.trim();addWord(lineTxt);}} catch (Exception e) {logger.error("讀取敏感詞文件失敗:"+e.getMessage());} finally {try {if ( reader != null){reader.close();}} catch (IOException e) {e.printStackTrace();}try {if ( isr != null){isr.close();}} catch (IOException e) {e.printStackTrace();}try {if ( is != null){is.close();}} catch (IOException e) {e.printStackTrace();}}} /*** 添加敏感詞到字典樹* @param lineTxt*/public void addWord(String lineTxt){TrieNode tempNode = rootNode;for (int i = 0; i < lineTxt.length(); i++) {Character c = lineTxt.charAt(i);/*** 過濾掉符號干擾*/if (isSymbol(c)){continue;}TrieNode node = tempNode.getSubNode(c);if (node == null){node = new TrieNode();tempNode.setSubNode(c,node);}tempNode = node;if (i == lineTxt.length() - 1){tempNode.setKeywordEnd(true);}}} /*** 判斷是否是一個符號* @param c* @return*/public boolean isSymbol(char c){int ic = (int)c;//0x2E80~0x9FFF是東亞文字范圍return !CharUtils.isAsciiAlphanumeric(c) && (ic < 0x2E80 || ic > 0x9FFF);}

過濾關(guān)鍵詞

/*** 過濾關(guān)鍵詞* @param text* @return*/public String filter(String text){StringBuilder result = new StringBuilder();String replacement = DEFAULT_REPLACEMENT;if (StringUtils.isBlank(text)){return text;}TrieNode tempNode = rootNode;int begin = 0;int position = 0;while (begin < text.length()){char c = text.charAt(position);//符號直接跳過if (isSymbol(c)){if (tempNode == rootNode){result.append(c);begin++;}position++;continue;}tempNode = tempNode.getSubNode(c);if (tempNode == null){result.append(text.charAt(begin));begin = begin + 1;position = begin;tempNode = rootNode;}else if (tempNode.isKeywordEnd()){result.append(replacement);begin = position + 1;position = begin;tempNode = rootNode;}else {position++;if (position == text.length()){result.append(text.charAt(begin));begin++;position = begin;tempNode = rootNode;}}}result.append(text.substring(begin));return result.toString();}

最后這里也許可以講一講,總算有一點可以講一下了,畢竟太簡單了,看代碼就能看懂,

  • tempNode指向的是篩選過程中字典樹中對應(yīng)字符的具體位置
  • begin指向的是以該字符開頭的敏感詞的開始位置,當(dāng)然這也不一定是一個敏感詞,如果字典樹中不存在該字符開頭的敏感詞就會以下一個字符為敏感詞開頭的來進(jìn)行篩選,即begin++,當(dāng)begin到文本的末尾即敏感詞過濾完畢
  • position的作用是幫助判斷以begin指向字符開頭是否存在敏感詞

好了,說完這三個指針感覺沒啥說的了,都在代碼中了。

總結(jié)

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

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