当前位置: 首页 > news >正文

基于DFA算法实现敏感词过滤

何为DFA

DFA,全称为Deterministic Finite Automaton,即确定有穷自动机确定有限状态自动机确定有限自动机

对于一个给定的属于该自动机的状态和一个属于该自动机字母表Σ的字符,它都能根据事先给定的转移函数转移到下一个状态(这个状态可以是先前那个状态)。

确定:状态以及引起状态转换的事件都是可确定的,不存在“意外”。

有穷:状态以及事件的数量都是可穷举的。

简单来说就是存储字符串每个字符,并判断到该字符为止是否属于敏感词

实现过程

存储:一次性的把所有的敏感词存储到了多个map中,就是下图表示这种结构

敏感词:冰毒、大麻、大坏蛋

检索的过程

执行上面的过程,就能匹配到内容中的敏感词了

代码实现

    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标志置1if (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;}

验证DFA算法

public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("坏蛋");list.add("混蛋");list.add("笨蛋");initMap(list);String content="我是一个坏人,但是不是坏蛋,也不是笨蛋";Map<String, Integer> map = matchWords(content);System.out.println(map);}

可以看到匹配结果是正确的(上面的代码可以直接封装成工具类使用)

// 封装后直接调用
// 初始化敏感词库SensitiveWordUtil.initMap(sensitiveList);// 查看内容中是否包含敏感词
Map<String, Integer> map = SensitiveWordUtil.matchWords(content);
if (map.size() > 0) {System.out.println("内容中存在敏感词");}

拓展延申

这个算法和之前遇到的字典树(Trie)算法很像,然后我就去搜索了一下两者的联系,发现DFA算法的核心就是构建一颗以敏感词为基础的多叉树,也就是字典树。字典树的每个节点代表一个状态,每条边代表一个字符,从一个状态到另一个状态的转移。当遍历完一个词后,将该词的最后一个字符的状态标记为结束(isEnd = true)

这样,我们可以通过这个DFA字典树,一个字符一个字符的检测输入的字符串,如果检测的字符在我们的敏感词树中,就进入命中的树,看下一个字符在不在树中,如果持续命中到最后一个字符,即idEnd = true,那么就是完全命中了,即存在敏感词

相关文章:

基于DFA算法实现敏感词过滤

何为DFA DFA&#xff0c;全称为Deterministic Finite Automaton&#xff0c;即确定有穷自动机、确定有限状态自动机或确定有限自动机 对于一个给定的属于该自动机的状态和一个属于该自动机字母表Σ的字符&#xff0c;它都能根据事先给定的转移函数转移到下一个状态&#xff0…...

模式识别与机器学习-无监督学习-聚类

无监督学习-聚类 监督学习&无监督学习K-meansK-means聚类的优点&#xff1a;K-means的局限性&#xff1a;解决方案&#xff1a; 高斯混合模型&#xff08;Gaussian Mixture Models&#xff0c;GMM&#xff09;多维高斯分布的概率密度函数&#xff1a;高斯混合模型&#xff…...

Python中property特性属性是什么

在Java中&#xff0c;通常在类中定义的成员变量为私有变量&#xff0c;在类的实例中不能直接通过对象.属性直接操作&#xff0c;而是要通过getter和setter来操作私有变量。 而在Python中&#xff0c;因为有property这个概念&#xff0c;所以不需要写getter和setter一堆重复的代…...

vue3 全局配置Axios实例

目录 前言 配置Axios实例 页面使用 总结 前言 Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于浏览器和 Node.js 环境。它提供了一种简单、一致的 API 来处理HTTP请求&#xff0c;支持请求和响应的拦截、转换、取消请求等功能。关于它的作用&#xff1a; 发起 HTTP …...

EI级 | Matlab实现TCN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测

EI级 | Matlab实现TCN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 EI级 | Matlab实现TCN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.【EI级】 Matlab实现TCN-BiGRU-Mult…...

WeNet语音识别分词制作词云图

在线体验 ,点击识别语音需要等待一会&#xff0c;文件太大缓存会报错 介绍 本篇博客将介绍如何使用 Streamlit、jieba、wenet 和其他 Python 库&#xff0c;结合语音识别&#xff08;WeNet&#xff09;和词云生成&#xff0c;构建一个功能丰富的应用程序。我们将深入了解代码…...

Proxyman:现代本地Web调试代理工具

1. 简介 1.1 什么是Proxyman&#xff1f; Proxyman是一款专为macOS设计的现代本地Web调试代理工具&#xff0c;它不仅支持macOS平台&#xff0c;还能无缝地与iOS和Android设备进行集成。作为一个网络调试工具&#xff0c;Proxyman的设计旨在提供高性能、直观且功能丰富的解决…...

k8s中DaemonSet实战详解

一、DaemonSet介绍 DaemonSet 的主要作用&#xff0c;是在 Kubernetes 集群里&#xff0c;运行一个 Daemon Pod。DaemonSet 只管理 Pod 对象&#xff0c;然后通过 nodeAffinity 和 Toleration 这两个调度器参数的功能&#xff0c;保证了每个节点上有且只有一个 Pod。 二、Daem…...

信号处理设计模式

问题 如何编写信号安全的应用程序&#xff1f; Linux 应用程序安全性讨论 场景一&#xff1a;不需要处理信号 应用程序实现单一功能&#xff0c;不需要关注信号 如&#xff1a;数据处理程序&#xff0c;文件加密程序&#xff0c;科学计算程序 场景二&#xff1a;需要处理信…...

Linux权限的基本理解

一:&#x1f6a9;Linux中的用户 1.1&#x1f966;用户的分类 &#x1f31f;在Linux中用户可以被分为两种用户: 超级用户(root):可以在Linux系统中做各种事情而不被约束普通用户:只能做有限的事情被权限约束 在实际操作时超级用户的命令提示符为#,普通用户的命令提示符为$,可…...

AI人工智能大模型讲师叶梓《基于人工智能的内容生成(AIGC)理论与实践》培训提纲

【课程简介】 本课程介绍了chatGPT相关模型的具体案例实践&#xff0c;通过实操更好的掌握chatGPT的概念与应用场景&#xff0c;可以作为chatGPT领域学习者的入门到进阶级课程。 【课程时长】 1天&#xff08;6小时/天&#xff09; 【课程对象】 理工科本科及以上&#xff0…...

nat地址转换

原理 将内网地址转换成外网地址 方式 掌握动态NAT的配置方法 掌握Easy IP的配置方法 掌握NAT Server的配置方法 实验 r1 r2 是内网 ar1 ip地址 ip add ip地址 掩码 ip route-static 0.0.0.0 0 192.168.1.254 默认网关 吓一跳网关 相等于设置了网关 ar2 …...

第12课 循环综合举例

文章目录 前言一、循环综合举例1. 质数判断问题2. 百人百砖问题3. 猴子吃桃问题4. 质因数分解问题5. 数字统计问题。 二、课后练习2. 末尾3位数问题3. 求自然常数e4. 数据统计问题5. 买苹果问题。6. 找5的倍数问题。 总结 前言 本课使用循环结构&#xff0c;介绍了以下问题的解…...

Tuxera NTFS for Mac2024免费Mac读写软件下载教程

在日常生活中&#xff0c;我们使用Mac时经常会遇到外部设备不能正常使用的情况&#xff0c;如&#xff1a;U盘、硬盘、软盘等等一系列存储设备&#xff0c;而这些设备的格式大多为NTFS&#xff0c;Mac系统对NTFS格式分区存在一定的兼容性问题&#xff0c;不能正常读写。 那么什…...

C++ 具名要求

此页面中列出的具名要求&#xff0c;是 C 标准的规范性文本中使用的具名要求&#xff0c;用于定义标准库的期待。 某些具名要求在 C20 中正在以概念语言特性进行形式化。在那之前&#xff0c;确保以满足这些要求的模板实参实例化标准库模板是程序员的重担。若不这么做&#xf…...

大创项目推荐 深度学习二维码识别

文章目录 0 前言2 二维码基础概念2.1 二维码介绍2.2 QRCode2.3 QRCode 特点 3 机器视觉二维码识别技术3.1 二维码的识别流程3.2 二维码定位3.3 常用的扫描方法 4 深度学习二维码识别4.1 部分关键代码 5 测试结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天…...

C++初阶——基础知识(函数重载与引用)

目录 1.命名冲突 2.命名空间 3.缺省参数 4.函数重载 1.函数重载的特点包括&#xff1a; 2.函数重载的好处包括&#xff1a; 3.引用 引用的特点包括 引用的主要用途包括 引用和指针 引用 指针 类域 命名空间域 局部域 全局域 第一个关键字 命名冲突 同一个项目之间冲…...

车载电子电器架构 —— 电子电气系统开发角色定义

车载电子电器架构 —— 电子电气系统开发角色定义 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 注:本文12000字,深度思考者进!!! 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的…...

最新Redis7哨兵模式(保姆级教学)

一定一定要把云服务器的防火墙打开一定要&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;否则不成功&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…...

Redis原理及常见问题

高性能之道 单线程模型基于内存操作epoll多路复用模型高效的数据存储结构redis的单线程指的是数据处理使用的单线程,实际上它主要包含 IO线程:处理网络消息收发主线程:处理数据读写操作,包括事务、Lua脚本等持久化线程:执行RDB或AOF时,使用持久化线程处理,避免主线程的阻…...

nvm 的安装及使用 (Node版本管理器)

目录 1、nvm 介绍 2、nvm安装 3、nvm 使用 4、node官网可以查看node和npm对应版本 5、nvm安装指定版本node 6、安装cli脚手架 1、nvm 介绍 NVM 全称 node.js version management &#xff0c;专门针对 node 版本进行管理的工具&#xff0c;通过它可以安装和切换不同版本的…...

【Yii2】数据库查询方法总结

目录 1.查找单个记录&#xff1a; 2.查找多个记录&#xff1a; 3.条件查询&#xff1a; 4.关联查询&#xff1a; 假设User模型有一个名为orders的多对一关联关系。 5.排序和分组&#xff1a; 6.数据操作&#xff1a; 7.事务处理&#xff1a; 8.命令查询&#xff1a; 9…...

区块链的三难困境是什么,如何解决?

人们需要保持社交、工作和睡眠之间的平衡&#xff0c;并且努力和谐相处。同样的概念也反映在区块链的三难困境中。 区块链三难困境是一个术语&#xff0c;指的是现有区块链的局限性&#xff1a;可扩展性、安全性和去中心化。这是一个存在了几十年的设计问题&#xff0c;其问题的…...

oCPC实践录 | oCPM的秘密

前言 笔者从这几方面介绍oCPM&#xff0c;并一一分析平台侧宣称的oCPM相比oCPC的优势&#xff0c;并解开其中的秘密。 1&#xff09;什么是oCPM? 2&#xff09;oCPC与oCPM的异同 3&#xff09;平台宣称oCPM的优势 4&#xff09;oCPM真正的秘密 5&#xff09;oCPM下的点击率与…...

【Linux Shell学习笔记】Linux Shell的位置参数与函数

一、位置参数 位置参数&#xff0c;也被称之为位置变量&#xff0c;通过位置参数&#xff0c;可以在执行程序的时候&#xff0c;向程序传递数据 1.1 shell接收参数的方法 1.2 向shell传递参数的方法 二、函数 2.1 函数基础 2.1.1 函数简介 函数本质上就是一个代码块&#xf…...

缓存cache和缓冲buffer的区别

近期被这两个词汇困扰了&#xff0c;感觉有本质的区别&#xff0c;搜了一些资料&#xff0c;整理如下 计算机内部的几个部分图如下 缓存&#xff08;cache&#xff09; https://baike.baidu.com/item/%E7%BC%93%E5%AD%98 提到缓存&#xff08;cache&#xff09;&#xff0c;就…...

Vue常见面试问答

vue响应式数据 vue2 Vue2 的对象数据是通过 Object.defineProperty 对每个属性进行监听&#xff0c;当对属性进行读取的时候&#xff0c;就会触发 getter&#xff0c;对属性进行设置的时候&#xff0c;就会触发 setter。 /** * 这里的函数 defineReactive 用来对 Object.def…...

Eureka相关面试题及答案

1、什么是Eureka&#xff1f; Eureka是一个由Netflix开发的服务发现&#xff08;Service Discovery&#xff09;工具&#xff0c;它是Spring Cloud生态系统中的一个关键组件。服务发现是微服务架构中的一个重要概念&#xff0c;它允许服务实例在启动时注册自己&#xff0c;以便…...

想要学会JVM调优,先掌握JVM内存模型和JVM运行原理

1、前言 今天将和你一起探讨Java虚拟机&#xff08;JVM&#xff09;的性能调优。 JVM算是面试中的高频问题了&#xff0c;通常情况下总会有人问到&#xff1a;请你讲解下 JVM 的内存模型&#xff0c;JVM 的 性能调优做过&#xff1f; 2、为什么 JVM 在 Java 中如此重要 首…...

详解C语言入门程序:HelloWorld.c

#include <stdio.h> // 头文件&#xff0c;使用<>编译系统会在系统头文件目录搜索在C语言中&#xff0c;#include 是预处理指令&#xff0c;用于将指定的头文件内容插入到当前源文件中。这里的 <stdio.h> 是一个标准库头文件&#xff0c;其中包含了与输入输出…...