自管理敏感词过滤
问题:文章审核不能过滤一些敏感词:私人侦探、针孔摄象、信用卡提现、广告代理、刻章办、出售答案、小额贷款…
需要完成的功能:自己维护一套敏感词,在文章审核的时候,需要验证文章是否包含这些敏感词
方案:
1、数据库模糊查询 效率低
2、String.index("")查找 数据库量大的话也是比较慢
3、全文检索 分词再匹配
4、DFA算法 确定有穷自动机(一种数据结构)
DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。
存储:一次性的把所有的敏感词存储到了多个map中。
敏感词:冰毒、大麻、大坏蛋
isEnd=0,不是敏感词结尾。isEnd=1,是敏感词结尾
执行过程:
工具类:
package com.heima.utils.common; import java.util.*; public class SensitiveWordUtil { public static Map<String, Object> dictionaryMap = new HashMap<>(); /** * 生成关键词字典库 * @param words * @return */ public static void initMap(Collection<String> words) { if (words == null) { System.out.println("敏感词列表不能为空"); return ; } // map初始长度words.size(),整个字典库的入口字数(小于words.size(),因为不同的词可能会有相同的首字) Map<String, Object> map = new HashMap<>(words.size()); // 遍历过程中当前层次的数据 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++) { // 遍历每个词的字 String key = String.valueOf(word.charAt(i)); // 当前字在当前层是否存在, 不存在则新建, 当前层数据指向下一个节点, 继续判断是否存在数据 Map<String, Object> wordMap = (Map<String, Object>) curMap.get(key); if (wordMap == null) { // 每个节点存在两个数据: 下一个节点和isEnd(是否结束标志) wordMap = new HashMap<>(2); wordMap.put("isEnd", "0"); curMap.put(key, wordMap); } curMap = wordMap; // 如果当前字是词的最后一个字,则将isEnd标志置1 if (i == len -1) { curMap.put("isEnd", "1"); } } } dictionaryMap = map; } /** * 搜索文本中某个文字是否匹配关键词 * @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)); // 获取当前key的下一个节点 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; } /** * 获取匹配的关键词和命中次数 * @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); // 添加关键词匹配次数 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="我是一个好人,没有枪"; //在文章查找是否包含敏感词 Map<String, Integer> map = matchWords(content); if(map.size() > 0){ System.out.println(map); }else{ System.out.println("没有找到敏感词"); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)