敏感词过滤

server/2024/12/22 19:28:26/

敏感词过滤通常是指在文本中检测并替换或删除不适宜的内容。基于DFA(Deterministic Finite Automaton,确定性有限自动机)算法的敏感词过滤是一种高效的方法。DFA算法通过构建一个状态机来匹配敏感词,其核心思想是将每个敏感词转换成一个状态机,然后通过遍历文本来检测敏感词。

所以我们需要有一个自定义的敏感词库,并将其存储在一种高效的数据结构中。

适应快速定位查找的数据结构我们很容易想到HashMap,但我们的理想结构是类似底层HashMap(hash+树的结构)

所以我们给出的数据结构为:
private static final Map<Character, Map> DFA = new HashMap<>();
这样的设计方便我们进行拓展

代码+解释:

java">public class SensitiveWordFilter {private static final Map<Character, Map> DFA = new HashMap<>();static {// 初始化DFA状态机,这里以"敏感词"和"词"为例initDFA("敏感");initDFA("感词");initDFA("啊");}public static void initDFA(String word) {Map<Character, Map> currMap = DFA;//引用DFAfor (char c : word.toCharArray()) {//判断这个词在不在我们构建的敏感词树中,如果不在我们需要为它创建/** computeIfAbsent是一个Map方法,它检查当前Map是否包含指定键(这里是敏感词中的字符ch)的映射。* 如果不存在这样的映射,它会使用提供的函数(k -> new HashMap<>())来创建一个新的Map,并将其作为该键的值。* */currMap = (Map<Character, Map>)currMap.computeIfAbsent(c, k -> new HashMap<>());}currMap.put('\0', null); // 终止符}//过滤敏感词public static String filter(String str) {StringBuilder sb = new StringBuilder();int length = str.length();for(int i = 0; i < length; i++){Map<Character, Map> currMap = DFA;char ch = str.charAt(i);int currIndex = i;boolean found = false;//是否发现敏感词//当前词匹配敏感词的首字母while(currIndex < length && currMap.containsKey(str.charAt(currIndex))){//取出此敏感词作根的树currMap = currMap.get(str.charAt(currIndex));//往下匹配其余词currIndex++;if(currMap.containsKey('\0')) {//说明当前匹配到底了found = true;//发现敏感词//替换敏感词replace(sb, i, currIndex);//跳过已找出的敏感词,继续匹配i = currIndex - 1;break;}}//首字母匹配上了但是最后没匹配上if(!found && currIndex > i){currIndex = i;}//说明该词不是敏感词,首字母就没匹配上if(i == currIndex) {sb.append(ch);}}return sb.toString();}public static void replace(StringBuilder sb, int start, int end) {for(int i = start; i < end; i++) {sb.append("*");}}public static void main(String[] args) {String text = "敏感词的示例词。";String filteredText = filter(text);System.out.println(filteredText); // 输出: 这是一个包含***的示例***}
}

 虽然DFA算法在很多场景下表现良好,但它并不是唯一的解决方案,也不一定是所有情况下最高效的算法,还有AC自动机和字典树(前缀树)等算法


http://www.ppmy.cn/server/152306.html

相关文章

怎样衡量电阻负载的好坏

电阻负载的好坏通常通过以下几种方法来衡量&#xff1a; 1. 测量电阻值&#xff1a;最直接的方法是使用万用表来测量电阻负载的电阻值。将万用表设置在适当的电阻档位&#xff0c;然后将测试笔连接到电阻负载的两个引脚上。如果电阻负载是好的&#xff0c;那么万用表应该显示一…

ES6中的map和set

Set ES6 提供了新的数据结构 Set。它类似于数组&#xff0c;但是成员的值都是唯一的&#xff0c;没有重复的值。 Set本身是一个构造函数&#xff0c;用来生成 Set 数据结构。 以下代码 const s new Set();[2, 3, 5, 4, 5, 2, 2].forEach(x > s.add(x));for (let i of s…

学习率是如何影响模型训练的?

一、概念 在深度学习中&#xff0c;学习率&#xff08;Learning Rate&#xff0c;LR&#xff09;是一个至关重要的超参数&#xff0c;它控制着模型参数在梯度下降过程中的更新步长。在每次训练迭代中&#xff0c;模型参数按照损失函数关于参数的梯度方向进行更新&#xff0c;而…

docker 软连接修改存储位置

查看docker路径 默认情况下Docker的存放位置为&#xff1a;/var/lib/docker&#xff0c;也可以通过如下命令查看docker存储路径 docker info | grep "Docker Root Dir" 停掉docker服务 systemctl stop docker 移动docker目录 mv /var/lib/docker /var/sda1/docker_…

【蓝桥杯每日一题】选数异或——线段树

选数异或 蓝桥杯每日一题 2024-12-16 选数异或 线段树 DP 思维 题目大意 给定一个长度为 n n n 的数组 A 1 , A 2 , ⋯ , A n A_1, A_2, \cdots, A_n A1​,A2​,⋯,An​ 和一个非负整数 x x x&#xff0c;给定 m m m 次查询&#xff0c;每次询问能否从某个区间 [ l , r ] …

独孤思维:最近有新副业项目?

01 最近很多读者问我。 有没有新的项目&#xff1f; 其实独孤这边有一大把项目。 但是结合和他们的过往接触。 即便给他们了&#xff0c;他们也不会上手。 即便上手了&#xff0c;也不会坚持下去。 因为之前他们基本上没有做成过一个项目。 都是在不断找&#xff0c;不…

前端开放性技术面试—面试题

1. 上线出现问题如何解决&#xff1f; 步骤&#xff1a; 立即响应&#xff1a;迅速确认问题的存在和影响范围。回滚&#xff1a;如果问题严重影响用户&#xff0c;考虑立即回滚到上一个稳定版本。日志分析&#xff1a;查看服务器日志、应用日志和前端日志&#xff0c;定位问题…

黑客术语3

19、免杀 : 就是通过加壳、加密、修改特征码、加花指令等等技术来修改程序&#xff0c; 使其逃过杀毒软件的查杀。 20 、加壳 : 就是利用特殊的算法&#xff0c;将 EXE 可执行程序或者 DLL 动态连接库文件的 编码进行改变&#xff08;比如实现压缩、加密&#xff09;&a…