java Map实现敏感词过滤 DFA算法

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的那一层,看当前的参数哪里出现了问题

在这里插入图片描述

最后如有疑问请留言

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云先生呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值