首页 > 编程语言 >java DFA算法模型

java DFA算法模型

时间:2022-10-18 16:00:50浏览次数:37  
标签:index java int text length 算法 DFA final match

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 敏感词过滤器
 */
public class Sensitive {

    /** 敏感词匹配规则 */
    public final static int MINIMUM = 1; // 最小匹配规则
    public final static int MAXIMUM = 2; // 最大匹配规则
    private final Map<String, Object> sensitive; // 敏感词库

    public Sensitive(Set<String> keywords) {
        // 初始化敏感词容器,减少扩容操作
        this.sensitive = new HashMap<>(keywords.size());
        // 将敏感词加入到HashMap中,构建DFA算法模型
        this.initialize(keywords);
    }

    /** 初始化敏感词库 */
    @SuppressWarnings("unchecked")
    private void initialize(final Set<String> keywords) {
        for (String keyword : keywords) {
            Map nowMap = this.sensitive;
            for (int i = 0; i < keyword.length(); i++) {
                char keyChar = keyword.charAt(i); // 转换成char型
                Object wordMap = nowMap.get(keyChar);
                if (wordMap != null) { // 存在该key则直接赋值
                    nowMap = (Map) wordMap;
                } else { // 不存在则则构建一个map,同时将isEnd设置为0,因为他不是最后一个
                    Map<String, String> newWordMap = new HashMap<>((1));
                    newWordMap.put("isEnd", "0"); // 不是最后一个
                    nowMap.put(keyChar, newWordMap);
                    nowMap = newWordMap;
                }
                if (i == keyword.length() - 1) {
                    nowMap.put("isEnd", "1"); // 最后一个
                }
            }
        }
    }

    /**
     * 检查文字中是否包含敏感字符
     * @param text 待检测的文本
     * @param starting  开始位置
     * @param match 匹配规则(1最小匹配规则;2最大匹配规则)
     * @return 存在则返回敏感词字符的长度,不存在返回0
     */
    private int checking(final String text, final int starting , final int match) {
        boolean ending = false; // 敏感词结束标识位(用于敏感词只有1位的情况)
        int matching = 0; // 匹配标识数默认为0
        Map nowMap = this.sensitive;
        for (int index = starting ; index < text.length(); index++) {
            char word = text.charAt(index);
            nowMap = (Map) nowMap.get(word); // 获取指定key
            if (nowMap == null) break; // 不存在则直接返回
            matching++; // 找到相应key,匹配标识+1
            // 存在则判断是否为最后一个,是则结束循环,返回匹配标识数
            if ("1".equals(nowMap.get("isEnd"))) {
                ending = true; // 结束标志位为true
                if (Sensitive.MINIMUM == match) {
                    break; // 最小规则,直接返回,最大规则还需继续查找
                }
            }
        }
        if (matching < 1 || !ending) { // 长度必须大于等于1
            matching = 0;
        }
        return matching;
    }

    /**
     * 获取文字中的敏感词
     * @param text 待查找的字符串
     * @param match 匹配规则(1最小匹配规则;2最大匹配规则)
     */
    private Set<String> searching(final String text, final int match) {
        final Set<String> sensitive = new HashSet<>(text.length());
        for (int index = 0, length = text.length(); index < length ; index++) {
            final int matching = this.checking(text, index, match); // 敏感字符检查
            if (matching > 0) { // 存在则加入集合中
                sensitive.add(text.substring(index, index + matching));
                index = index + matching - 1; // 减1的原因是因为for会自增
            }
        }
        return sensitive;
    }

    /**
     * 判断文字是否包含敏感字符
     * @param text 待检测的文本
     * @param match  匹配规则(1最小匹配规则;2最大匹配规则)
     */
    public final boolean contains(final String text, final int match) {
        for (int index = 0, length = text.length(); index < length; index++) {
            final int matching = this.checking(text, index, match);
            if (matching > 0) {
                return true; // 包含
            }
        }
        return false; // 不包含
    }

    /**
     * 使用“*”替换敏感字字符
     * @param text 待替换的字符
     * @param match 匹配规则(1最小匹配规则;2最大匹配规则)
     */
    public final String replace(String text, int match) {
        final String replace = "*";
        return replace(text, match, replace);
    }

    /**
     * 替换敏感字字符
     * @param text 待替换的字符
     * @param match 匹配规则(1最小匹配规则;2最大匹配规则)
     * @param replace 替换字符,默认*
     */
    public final String replace(final String text, final int match, final String replace) {
        String result = text;
        // 获取所有的敏感词
        final Set<String> sensitive = this.searching(text, match);
        // 替换同等长度的字符
        for (String element : sensitive) {
            final int length = element.length();
            final String newing = this.newing(replace, length);
            result = result.replaceAll(element, newing);
        }
        return result;
    }

    /**
     * 获取替换字符串
     * @param replace 替换字符
     * @param length 替换长度
     */
    private String newing(final String replace, final int length) {
        final StringBuilder builder = new StringBuilder();
        for (int index = 0; index < length; index++) {
            builder.append(replace);
        }
        return builder.toString();
    }

}

java 得dfa敏感词过滤算法!供大家参考!

标签:index,java,int,text,length,算法,DFA,final,match
From: https://www.cnblogs.com/ruber/p/16802857.html

相关文章

  • java.base.jmod
    /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods$jmodlistjava.base.jmod|wc-l5761classes/module-info.classclasses/apple/security/AppleProvid......
  • JAVA获取jvm和操作系统相关信息
    JAVA获取jvm和操作系统相关信息背景今日搬砖......
  • Java反射
    简介Reflection(反射)是Java被视为动态语言的关键。反射机制允许程序在执行期借助ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。加载完类之......
  • 银行家算法
    #include<iostream>#include<vector>#include<string> usingnamespacestd;typedefstruct{ intA; intB; intC;}MAX,ALLOCATION,NEED,AVAILABLE,WORK;......
  • java数据结构与算法
    直接在java中一直使用原生的Stack作为栈,看到大佬们都改用Deque了,因此使用Deque作为栈做一个练习。这是leetCode一个题目,我直接截个图吧  本题目可以分解为两个问题:......
  • 一文详尽系列之K-means算法
    K-means是我们最常用的基于距离的聚类算法,其认为两个目标的距离越近,相似度越大。算法1.1牧师-村民模型​K-means有一个著名的解释:牧师—村民模型:有四个牧师去郊区布道,一......
  • 一文详尽系列之EM算法
    EM算法,全称ExpectationMaximizationAlgorithm。期望最大算法是一种迭代算法,用于含有隐变量(HiddenVariable)的概率参数模型的最大似然估计或极大后验概率估计。思想EM算......
  • 力扣523(java)-连续的子数组和(中等)
    题目:给你一个整数数组nums和一个整数 k,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小至少为2,且子数组元素总和为k的倍数。如果存......
  • Java并发编程学习7-阻塞队列
    阻塞队列介绍阻塞队列之前,先来介绍下队列Queue。Queue用来临时保存一组等待处理的元素。它提供了几种非阻塞队列实现,如下:ConcurrentLinkedQueue,这是一个传统的先进先出......
  • JavaScript 获取两个时间相差的周数
    exportfunctiongetWeek(date1,date2){letd1=newDate(date1);letd2=newDate(date2);console.log(Math.ceil(parseInt(((d2-d1)/(1000*3......