敏感词过滤算法的实现
生活随笔
收集整理的這篇文章主要介紹了
敏感词过滤算法的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近一直在做項目,突然想起來好久沒有寫過博客了,于是就有了這篇博客。這篇博客的目的就是為了在自己忘記的時候可以快速撿起來。好了,廢話不多說了,以下就是正文。
要從哪里講起呢,先講講打算怎么做吧
這個算法是采用字典樹(也就是多叉樹)來存儲敏感詞,然后通過三個指針來對文本進行篩選,算了,我文字描述太差了,上圖花的時間太多,直接上代碼吧!
首先,需要定義一個字典樹結構
private class TrieNode{/*** 用來存儲子節點*/private Map<Character,TrieNode> subNodes = new HashMap<>();/*** 用來表示敏感詞的終結,true為終結*/private boolean end = false;/*** 設置子節點* @param key* @param node*/public void setSubNode(Character key,TrieNode node){subNodes.put(key,node);}/*** 獲取子節點* @param key* @return*/public TrieNode getSubNode(Character key){return subNodes.get(key);}/*** 設置本節點是否是敏感詞的終結* @param end*/public void setKeywordEnd(boolean end){this.end = end;}/*** 判斷是否是敏感詞的終結* @return*/public boolean isKeywordEnd(){return this.end;}/*** 獲取子節點的數量* @return*/public int getSubNodeCount(){return subNodes.size();}}哦豁!發現沒有什么可以講的,都已經注釋了,那下一個吧
對字典樹進行初始化
@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);}過濾關鍵詞
/*** 過濾關鍵詞* @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指向的是篩選過程中字典樹中對應字符的具體位置
- begin指向的是以該字符開頭的敏感詞的開始位置,當然這也不一定是一個敏感詞,如果字典樹中不存在該字符開頭的敏感詞就會以下一個字符為敏感詞開頭的來進行篩選,即begin++,當begin到文本的末尾即敏感詞過濾完畢
- position的作用是幫助判斷以begin指向字符開頭是否存在敏感詞
好了,說完這三個指針感覺沒啥說的了,都在代碼中了。
總結
以上是生活随笔為你收集整理的敏感词过滤算法的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: socket api中send()和re
- 下一篇: 蜡烛节能车模