java Map实现敏感词过滤 DFA算法
首先,DFA算法是啥
我的理解是,我们现在所接触的网络空间,难免鱼龙混杂,一些特殊意义,或满是芬芳气息的词汇在大多数地方都会屏蔽掉,或者用无意义的符号替换。
举个例子就是王者荣耀聊天系统,你如果打字出现芬芳气息的词汇,就会给你的词汇替换成*,今天要实现的就是这样的功能。
一、你可以自己去网上找找敏感词的词库
把它拿来作为测试的对象。当然了下面我也提供链接,需要的请自行下载。敏感词库
二、接下来是如何将词库里面的每个词汇都转为一棵大树的一部分
类似这样的一颗树,怎么建呢?
1、一个外层循环所有的敏感词,循环每个敏感词的每一个字符看Map中有没有,注意这里的Map是我的根目录
2、有的话就循环判断,进一层的字符在temp中是否存在,这里的temp是一个当前目录的指针
3、有的话就继续判断,没有的话就把当前的Map加入没有的字符
4、一定要注意的是有一个temp是指向当前目录的指针,指针要考虑什么时候是需要回来的
转换代码如下:
public static Map<Character,Map> totran(List<String> wo,Map<Character, Map> maps, Map<Character, Map> temstap){
for (int i = 0; i < wo.size(); i++) {
//一定要注意指针要回来
temstap = maps;
char[] chars = wo.get(i).toCharArray();
for (int j = 0; j < chars.length; j++) {
if (temstap.containsKey(chars[j])) {
temstap = temstap.get(chars[j]);
} else {
Map<Character, Map> news = new HashMap<>();
temstap.put(chars[j], news);
temstap = news;
//一定要注意指针要回来
}
}
temstap.put('\t', null);
}
return maps;
}
三、将文章中的敏感词替换
有了上面的铺垫,下面的也就水到渠成
/**
* 将文章与敏感词Map结构进行匹配,将敏感词替换为‘*’
*
* @param str
* @param maps
* @param temstap
*/
public static char[] tranfro(String str, Map<Character, Map> maps, Map<Character, Map> temstap) {
temstap = maps;
int c = 0;
//c 和 j 都是我用的标志位,同样要注意什么时候要回来
int j = 1;
char[] charss = str.toCharArray();
for (int i = 0; i < str.length(); i++) {
if (temstap.containsKey(charss[i])) {
temstap = temstap.get(charss[i]);
c = c + 1;
if (temstap.containsKey('\t')) {
while (i - c + j != i + 1) {
charss[i - c + j] = '*';
j++;
}
c = 0;
j = 1;
//c 和 j 都是我用的标志位,同样要注意什么时候要回来
temstap = maps;
}
} else {
i = i - c;
c = 0;
//c 和 j 都是我用的标志位,同样要注意什么时候要回来
//标志位变动的时候,考虑全所有指针要不要变
temstap = maps;
}
}
return charss;
}
全部源代码:
package com.example.demo.newyears;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author:Yun
* @Date:2022/01/06/13:44
* @Description:
**/
public class TestMap {
private static final String url = "jdbc:mysql://121.196.23.247:33306/library?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
private static final String userName = "root";
private static final String passwd = "!QAZ@WSX3edc";
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try (
Connection conn = DriverManager.getConnection(url, userName, passwd);
PreparedStatement ps = conn.prepareStatement("select name from sensitive_words ;")) {
ResultSet rs = ps.executeQuery();
//用List来存放敏感词
List<String> wo = new ArrayList<>();
while (rs.next()) {
wo.add(rs.getString("name"));
}
Map<Character, Map> maps = new HashMap<>(); //根目录
// Map<Character, Map> temstap ; //临时
Map<Character, Map> temstap = new HashMap<>();
System.out.println(totran(wo, maps, temstap));
rs.close();
//将文章与敏感词Map结构进行匹配,将敏感词替换为‘*’
String str = "结婚证中国二等奖让";
Map<Character, Map> tem = new HashMap<>();
System.out.println(tranfro(str, maps, tem));
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public static Map<Character, Map> totran(List<String> wo, Map<Character, Map> maps, Map<Character, Map> temstap) {
for (int i = 0; i < wo.size(); i++) {
temstap = maps;
char[] chars = wo.get(i).toCharArray();
for (int j = 0; j < chars.length; j++) {
if (temstap.containsKey(chars[j])) {
temstap = temstap.get(chars[j]);
} else {
Map<Character, Map> news = new HashMap<>();
temstap.put(chars[j], news);
temstap = news;
}
}
temstap.put('\t', null);
}
return maps;
}
/**
* 将文章与敏感词Map结构进行匹配,将敏感词替换为‘*’
*
* @param str
* @param maps
* @param temstap
*/
public static char[] tranfro(String str, Map<Character, Map> maps, Map<Character, Map> temstap) {
temstap = maps;
int c = 0;
int j = 1;
char[] charss = str.toCharArray();
for (int i = 0; i < str.length(); i++) {
if (temstap.containsKey(charss[i])) {
temstap = temstap.get(charss[i]);
c = c + 1;
if (temstap.containsKey('\t')) {
while (i - c + j != i + 1) {
charss[i - c + j] = '*';
j++;
}
c = 0;
j = 1;
temstap = maps;
}
} else {
i = i - c;
c = 0;
//标志位变动的时候,考虑全所有指针要不要变
temstap = maps;
}
}
return charss;
}
}
这里想和大家分享一个很有价值的东西:
打断点,dubug看自己的循环哪里有问题,出现了意料外的情况,大多数都是自己循环的条件没写对,或漏了条件没写回归。
点这里你可以直接去,出现bug的那一层,看当前的参数哪里出现了问题
最后如有疑问请留言