利用 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, ...
随机推荐
- mysql安装与sqlyog安装
首先是mysql安装,参考下面两个链接 https://www.cnblogs.com/gengyufei/p/11735358.html#_label4 https://www.jb51.net/a ...
- 读完此文让你了解各个queue的原理
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作.通俗来讲,就是一个队列中,早来的排在前面,后来的就在队尾,而这个队列大多只有一个出口和入口的单项队列.Queue的重要 ...
- saltstack 自动化运维
salt介绍 saltstack是由thomas Hatch于2011年创建的一个开源项目,设计初衷是为了实现一个快速的远程执行系统. salt强大吗 系统管理员日常会进行大量的重复性操作,例如安装软 ...
- Java面向基础概述和三大特性
Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心.围绕着 Java 类和 Java 对象,有三大基本特性:封装是 Java 类的编写规范.继承是类与类之间联系的一种形式.而多态 ...
- C# Lazy Loading
前言 按需加载对象延迟加载实际是推迟进行创建对象,直到对其调用后才进行创建初始化,延迟(懒加载)的好处是提高系统性能,避免不必要的计算以及不必要的资源浪费. 常规有这些情况: 对象创建成本高且程序可能 ...
- Djangoday1 入门及第一个apphelloworld
1 Django基础指令新建一个django project新建app创建数据库表,更新数据库表或字段使用开发服务器清空数据库创建超级管理员导出数据 导入数据Django 项目环境终端数据库命令行更多 ...
- spring boot 中@Mapper和@Repository的区别
0--前言 @Mapper和@Repository是常用的两个注解,两者都是用在dao上,两者功能差不多,容易混淆,有必要清楚其细微区别: 1--区别 @Repository需要在Spring中配置扫 ...
- io流函数略解(java)[一]
背景 最近在做安卓的过程中,因为im app经常涉及到读取与写入的io问题,所以总结一下.下文使用的是java语言. 实践 材料: java eclipse 1.File 在操作系统中我们一般能看到的 ...
- WPF最简单的分页控件
背景:最近在写项目的时候需要写一个简单的分页功能,因项目需要,没有改为MVVM模式,只需要在后台实现 1.呈现效果如下: 接下来就来上代码,看看怎么实现的 1.界面代码 <StackPanel ...
- python 拷贝文件夹下的文件 到 另一个文件夹
import os,shutil def copy_search_file(srcDir, desDir): ls = os.listdir(srcDir) for line in ls: fileP ...