利用 DFA 算法实现文字过滤
一、DFA 算法简介
在实现文字过滤的算法中,DFA是唯一比较好的实现算法。
DFA 全称为:Deterministic Finite Automaton,即确定有穷自动机。其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每条边上标记有一个符号,其中一个状态是初态,某些状态是终态。但不同于不确定的有限自动机,DFA 中不会有从同一状态出发的两条边标志有相同的符号。
简单点说就是,它是是通过 event 和当前的 state 得到下一个 state,即 event + state= nextstate。理解为系统中有多个节点,通过传递进入的 event,来确定走哪个路由至另一个节点,而节点是有限的。
二、DEA 算法实践敏感词过滤
1. 敏感词库构造
以王八蛋和王八羔子两个敏感词来进行描述,首先构建敏感词库,该词库名称为SensitiveMap,这两个词的二叉树构造为:
用 hash 表构造为:
{
"王":{
"isEnd":"0",
"八":{
"羔":{
"子":{
"isEnd":"1"
},
"isEnd":"0"
},
"isEnd":"0",
"蛋":{
"isEnd":"1"
}
}
}
}
怎么用代码实现这种数据结构呢?
/**
* 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型
*
* @param keyWordSet 敏感词库
*/
public Map<String, Object> addSensitiveWordToHashMap(Set<String> keyWordSet) {
//初始化敏感词容器,减少扩容操作
Map<String, Object> map = new HashMap(Math.max((int) (keyWordSet.size() / .75f) + 1, 16));
//迭代keyWordSet
for (String aKeyWordSet : keyWordSet) {
Map nowMap = map;
for (int i = 0; i < aKeyWordSet.length(); i++) {
//转换成char型
char keyChar = aKeyWordSet.charAt(i);
//获取
Object wordMap = nowMap.get(keyChar);
//如果存在该key,直接赋值
if (wordMap != null) {
nowMap = (Map) wordMap;
} else { //不存在则,则构建一个map,同时将isEnd设置为0
Map<String, String> newWorMap = new HashMap<>(3);
newWorMap.put("isEnd", "0");
nowMap.put(keyChar, newWorMap);
nowMap = newWorMap;
}
//判断最后一个
if (i == aKeyWordSet.length() - 1) {
nowMap.put("isEnd", "1");
}
}
}
return map;
}
2. 敏感词过滤
以上面例子构造出来的 SensitiveMap 为敏感词库进行示意,假设这里输入的关键字为:王八不好,流程图如下:
怎么用代码实现这个流程图逻辑呢?
/**
* 查找字符串中是否包含敏感字符
*
* @param txt 输入的字符串
* @return 如果存在,则返回敏感字符串;不存在,则返回空字符串
*/
public static String findSensitiveWord(String txt) {
SensitiveWordInit sensitiveWordInit = SpringContextHolder.getBean(SensitiveWordInit.class);
Map<String, Object> sensitiveWordMap = sensitiveWordInit.getSensitiveWordMap();
StringBuilder sensitiveWord = new StringBuilder();
// 敏感词结束标志位,表示匹配到了最后一位
boolean flag = false;
for (int i = 0; i < txt.length(); i++) {
char word = txt.charAt(i);
// 获取指定 key
sensitiveWordMap = (Map) sensitiveWordMap.get(word);
// 不存在,直接返回没有敏感词
if (sensitiveWordMap == null) {
break;
}
//存在,存储该敏感词,并判断是否为最后一个
sensitiveWord.append(word);
//如果为最后一个匹配规则,结束循环
if ("1".equals(sensitiveWordMap.get("isEnd"))) {
flag = true;
break;
}
}
// 表示匹配到了完整敏感词
if (flag == true) {
return sensitiveWord.toString();
}
return "";
}
三、优化思路
对于“王*八&&蛋”这样的词,中间填充了无意义的字符来混淆,在我们做敏感词搜索时,同样应该做一个无意义词的过滤,当循环到这类无意义的字符时进行跳过,避免干扰。
利用 DFA 算法实现文字过滤的更多相关文章
- Java 利用DFA算法 屏蔽敏感词
原文:http://www.open-open.com/code/view/1435214601278 import java.io.BufferedReader; import java.io.Fi ...
- 敏感词过滤的算法原理之DFA算法
参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有 ...
- java实现敏感词过滤(DFA算法)
小Alan在最近的开发中遇到了敏感词过滤,便去网上查阅了很多敏感词过滤的资料,在这里也和大家分享一下自己的理解. 敏感词过滤应该是不用给大家过多的解释吧?讲白了就是你在项目中输入某些字(比如输入xxo ...
- Java过滤敏感词语/词汇---DFA算法
最近网站需要在评论.投稿等地方过滤敏感词汇,于是在网上查找了相关教程,特此整理分享. 关于DFA算法,详细的可以去http://blog.csdn.net/u013378306/article/det ...
- Java实现敏感词过滤 - DFA算法
Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...
- 使用DFA算法对敏感词进行过滤
项目目录结构如下: 其中resources资源目录中: stopwd.txt :停顿词,匹配时间直接过滤. wd.txt:敏感词库. 1.WordFilter敏感词过滤类: package com.s ...
- 敏感词汇过滤DFA算法
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- 基于DFA算法、RegExp对象和vee-validate实现前端敏感词过滤
面临敏感词过滤的问题,最简单的方案就是对要检测的文本,遍历所有敏感词,逐个检测输入的文本是否包含指定的敏感词. 很明显上面这种实现方法的检测时间会随着敏感词库数量的增加而线性增加.系统会因此面临性能和 ...
- DFA算法实现敏感词过滤
DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate.理解为系统中有多个节点,通过传递进入的event, ...
随机推荐
- PHP 的 self 关键字用法
之前有人询问 self 关键字的用法,答案是比较明显的:静态成员函数内不能用 this 调用非成员函数,但可以用 self 调用静态成员函数/变量/常量:其他成员函数可以用 self 调用静态成员函数 ...
- ArcGIS Desktop10.4安装教程
准备内容 安装环境:win10*64位专业版 安装文件:ArcGIS_Desktop_1041_150996.iso 破解文件:10.4.1crackOnly 请都以管理员身份运行安装程序 安装步骤 ...
- PHP与Python进行数据交互
最近,决定在一个项目用tp5进行APP接口开发,用Python做数据分析,然后这就面临一个问题:PHP和Python如何进行数据交互? 思路 我解决此问题的方法是利用了PHP的passthru函数来调 ...
- Python3 之 列表推导式
列表推导式(又称列表解析式)提供了一种简明扼要的方法来创建列表. 它的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是 0 个或多个 for 或者 if 语句.那个表达式可以是任意的, ...
- SQL语句实用技巧1
--显示行号 select *, ROW_NUMBER() OVER(Order by TYPENAME ) AS RowNumber from ( select distinct TYPENAME ...
- idea为什么maven工具栏下面没有dependencies跟Plugins
刚刚新建的springboot项目,然后进来就是这样子 网上查找资料有些说是maven版本的问题,但是对于我的问题并没有得到解决. 现在是2019年12月4日16:23:07,依然没有找到解决方法,不 ...
- 虚拟化--思杰citrix
目前虚拟化主要有vmware,微软,思杰 一:从硬件搭建开始 硬件需要问的几个问题: a.负载均衡.防火墙.路由器怎么配置? b.新增一块存储的话,怎么新增? 二:安装citrix xen serve ...
- 学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文(下)
[摘要] 除了范围索引之外,点查找的Hash Map在DBMS中起着类似或更重要的作用. 从概念上讲,Hash Map使用Hash函数来确定性地将键映射到数组内的随机位置(参见图[9 ],只有4位开销 ...
- [动图演示]Redis 持久化 RDB/AOF 详解与实践
Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集 合.以及散列等,并且还支持多种排序功能. 什么叫持 ...
- 学习ThinkPHP的第21天---关联预载入、关联统计
ThinkPHP关联预载入 预载入的作用是减少执行SQL语句,进而提升程序的性能. public function join(){ //用于监听SQL Db::listen(function ($sq ...