项目目录结构如下:

其中resources资源目录中:

stopwd.txt :停顿词,匹配时间直接过滤。

wd.txt:敏感词库。

1、WordFilter敏感词过滤类:

 package com.skyer.sensitivewdfilter;

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;

 /**
  * 思路: 创建一个FilterSet,枚举了0~65535的所有char是否是某个敏感词开头的状态
  *
  * 判断是否是 敏感词开头 | | 是 不是 获取头节点 OK--下一个字 然后逐级遍历,DFA算法
  */
 public class WordFilter {

     private static final FilterSet set = new FilterSet(); // 存储首字
     private static final Map<Integer, WordNode> nodes = new HashMap<Integer, WordNode>(1024, 1); // 存储节点
     private static final Set<Integer> stopwdSet = new HashSet<Integer>(); // 停顿词
     private static final char SIGN = '*'; // 敏感词过滤替换

     static {
         try {
             long a = System.nanoTime();
             init();
             a = System.nanoTime() - a;
             System.out.println("加载时间 : " + a + "ns");
             System.out.println("加载时间 : " + a / 1000000 + "ms");
         } catch (Exception e) {
             throw new RuntimeException("初始化过滤器失败");
         }
     }

     private static void init() {
         // 获取敏感词
         addSensitiveWord(readWordFromFile("wd.txt"));
         addStopWord(readWordFromFile("stopwd.txt"));
     }

     /**
      * 增加敏感词
      */
     private static List<String> readWordFromFile(String path) {
         List<String> words;
         BufferedReader br = null;
         try {
             br = new BufferedReader(new InputStreamReader(WordFilter.class.getClassLoader().getResourceAsStream(path)));
             words = new ArrayList<String>(1200);
             for (String buf = ""; (buf = br.readLine()) != null;) {
                 if (buf == null || buf.trim().equals(""))
                     continue;
                 words.add(buf);
             }
         } catch (Exception e) {
             throw new RuntimeException(e);
         } finally {
             try {
                 if (br != null)
                     br.close();
             } catch (IOException e) {
             }
         }
         return words;
     }

     /**
      * 增加停顿词
      */
     private static void addStopWord(final List<String> words) {
         if (words != null && words.size() > 0) {
             char[] chs;
             for (String curr : words) {
                 chs = curr.toCharArray();
                 for (char c : chs) {
                     stopwdSet.add(charConvert(c));
                 }
             }
         }
     }

     /**
      * 添加DFA节点
      */
     private static void addSensitiveWord(final List<String> words) {
         if (words != null && words.size() > 0) {
             char[] chs;
             int fchar;
             int lastIndex;
             WordNode fnode; // 首字母节点
             for (String curr : words) {
                 chs = curr.toCharArray();
                 fchar = charConvert(chs[0]);
                 if (!set.contains(fchar)) {// 没有首字定义
                     set.add(fchar);// 首字标志位 可重复add
                     fnode = new WordNode(fchar, chs.length == 1);
                     nodes.put(fchar, fnode);
                 } else {
                     fnode = nodes.get(fchar);
                     if (!fnode.isLast() && chs.length == 1)
                         fnode.setLast(true);
                 }
                 lastIndex = chs.length - 1;
                 for (int i = 1; i < chs.length; i++) {
                     fnode = fnode.addIfNoExist(charConvert(chs[i]), i == lastIndex);
                 }
             }
         }
     }

     /**
      * 过滤判断 将敏感词转化为成屏蔽词
      */
     public static final String doFilter(final String src) {
         char[] chs = src.toCharArray();
         int length = chs.length;
         int currc;
         int k;
         WordNode node;
         for (int i = 0; i < length; i++) {
             currc = charConvert(chs[i]);
             if (!set.contains(currc)) {
                 continue;
             }
             node = nodes.get(currc);
             if (node == null)
                 continue;
             boolean couldMark = false;
             int markNum = -1;
             if (node.isLast()) {
                 couldMark = true;
                 markNum = 0;
             }
             k = i;
             for (; ++k < length;) {
                 int temp = charConvert(chs[k]);
                 if (stopwdSet.contains(temp))
                     continue;
                 node = node.querySub(temp);
                 if (node == null)
                     break;
                 if (node.isLast()) {
                     couldMark = true;
                     markNum = k - i;
                 }
             }
             if (couldMark) {
                 for (k = 0; k <= markNum; k++) {
                     chs[k + i] = SIGN;
                 }
                 i = i + markNum;
             }
         }

         return new String(chs);
     }

     /**
      * 是否包含敏感词
      */
     public static final boolean isContains(final String src) {
         char[] chs = src.toCharArray();
         int length = chs.length;
         int currc;
         int k;
         WordNode node;
         for (int i = 0; i < length; i++) {
             currc = charConvert(chs[i]);
             if (!set.contains(currc)) {
                 continue;
             }
             node = nodes.get(currc);
             if (node == null)
                 continue;
             boolean couldMark = false;
             if (node.isLast()) {
                 couldMark = true;
             }
             k = i;
             for (; ++k < length;) {
                 int temp = charConvert(chs[k]);
                 if (stopwdSet.contains(temp))
                     continue;
                 node = node.querySub(temp);
                 if (node == null)
                     break;
                 if (node.isLast()) {
                     couldMark = true;
                 }
             }
             if (couldMark) {
                 return true;
             }
         }

         return false;
     }

     /**
      * 大写转化为小写 全角转化为半角
      */
     private static int charConvert(char src) {
         int r = BCConvert.qj2bj(src);
         return (r >= 'A' && r <= 'Z') ? r + 32 : r;
     }

 }

WordFilter.java

其中:

isContains :是否包含敏感词

doFilter:过滤敏感词

2、WordNode敏感词节点:

 package com.skyer.sensitivewdfilter;

 import java.util.LinkedList;
 import java.util.List;

 public class WordNode {

     private int value; // 节点名称

     private List<WordNode> subNodes; // 子节点

     private boolean isLast; // 默认false

     public WordNode(int value) {
         this.value = value;
     }

     public WordNode(int value, boolean isLast) {
         this.value = value;
         this.isLast = isLast;
     }

     /**
      * @return 就是传入的subNode
      */
     private WordNode addSubNode(final WordNode subNode) {
         if (subNodes == null)
             subNodes = new LinkedList<WordNode>();
         subNodes.add(subNode);
         return subNode;
     }

     /**
      * 有就直接返回该子节点, 没有就创建添加并返回该子节点
      */
     public WordNode addIfNoExist(final int value, final boolean isLast) {
         if (subNodes == null) {
             return addSubNode(new WordNode(value, isLast));
         }
         for (WordNode subNode : subNodes) {
             if (subNode.value == value) {
                 if (!subNode.isLast && isLast)
                     subNode.isLast = true;
                 return subNode;
             }
         }
         return addSubNode(new WordNode(value, isLast));
     }

     public WordNode querySub(final int value) {
         if (subNodes == null) {
             return null;
         }
         for (WordNode subNode : subNodes) {
             if (subNode.value == value)
                 return subNode;
         }
         return null;
     }

     public boolean isLast() {
         return isLast;
     }

     public void setLast(boolean isLast) {
         this.isLast = isLast;
     }

     @Override
     public int hashCode() {
         return value;
     }

 }

WordNode.java

3、测试类:

 package com.skyer.test;

 import org.junit.Test;

 import com.skyer.sensitivewdfilter.WordFilter;

 public class TestSensitivewd {

     @Test
     public void TestFilter() {
         String s = ""; // 这里写你要过滤的句子(我这里不能写,否则会给博客园屏蔽掉)
         System.out.println("解析问题: " + s);
         System.out.println("解析字数 : " + s.length());
         String re;
         long nano = System.nanoTime();
         re = WordFilter.doFilter(s);
         nano = (System.nanoTime() - nano);
         System.out.println("解析时间 : " + nano + "ns");
         System.out.println("解析时间 : " + nano / 1000000 + "ms");
         System.out.println(re);
         System.out.println();

         nano = System.nanoTime();
         System.out.println("是否包含敏感词: " + WordFilter.isContains(s));
         nano = (System.nanoTime() - nano);
         System.out.println("解析时间 : " + nano + "ns");
         System.out.println("解析时间 : " + nano / 1000000 + "ms");
     }

 }

TestSensitivewd.java

4、测试结果:

原文参考:http://blog.csdn.net/fengshizty/article/details/52373005

DFA知识:http://www.cnblogs.com/naaoveGIS/archive/2016/10/14/5960352.html

使用DFA算法对敏感词进行过滤的更多相关文章

  1. DFA算法实现敏感词过滤

    DFA算法:即确定有穷自动机,简单点说就是,它是是通过event和当前的state得到下一个state,即event+state=nextstate.理解为系统中有多个节点,通过传递进入的event, ...

  2. Java 利用DFA算法 屏蔽敏感词

    原文:http://www.open-open.com/code/view/1435214601278 import java.io.BufferedReader; import java.io.Fi ...

  3. 如何用Python实现敏感词的过滤

    题目要求如下: 从文件解析敏感词,从终端获取用户输入.根据敏感词对用户输入进行过滤.这里过滤需要考虑不止一个过滤词:即将读取的所有过滤词,放进一个列表,用屏蔽词检索用户输入,如果有屏蔽词,则将其替换为 ...

  4. Java实现敏感词过滤 - DFA算法

    Java实现DFA算法进行敏感词过滤 封装工具类如下: 使用前需对敏感词库进行初始化: SensitiveWordUtil.init(sensitiveWordSet); package cn.swf ...

  5. 敏感词过滤的算法原理之DFA算法

    参考文档 http://blog.csdn.net/chenssy/article/details/26961957 敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有 ...

  6. DFA和trie特里实现敏感词过滤(python和c语言)

    今天的项目是与完成python开展,需要使用做关键词检查,筛选分类,使用前c语言做这种事情.有了线索,非常高效,内存小了,检查快. 到达python在,第一个想法是pip基于外观的c语言python特 ...

  7. Java实现敏感词过滤

    敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...

  8. Java实现敏感词过滤(转)

    敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...

  9. Jsp敏感词过滤

    Jsp敏感词过滤 大部分论坛.网站等,为了方便管理,都进行了关于敏感词的设定. 在多数网站,敏感词一般是指带有敏感政治倾向(或反执政党倾向).暴力倾向.不健康色彩的词或不文明语,也有一些网站根据自身实 ...

随机推荐

  1. linux XAMPP安装与使用

    linux安装 下载好后考至目录, chmod +x  接安装包 在执行 ./ 接安装包 启动 XAMPP /opt/lampp/lampp start 停止 XAMPP /opt/lampp/lam ...

  2. [编织消息框架][JAVA核心技术]动态代理应用5-javassist

    基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...

  3. WPF中的RichTextBox

    原文链接:http://blog.csdn.net/wuzhengqing1/article/details/7010902 取出richTextBox里面的内容 第一种方法:将richTextBox ...

  4. C#7的新语法

    阅读目录 out变量 元组(Tuples) 模式匹配(Pattern matching) 本地引用和返回(Ref locals and returns) 本地函数(Local functions) 表 ...

  5. 谱聚类(Spectral clustering)分析(1)

    作者:桂. 时间:2017-04-13  19:14:48 链接:http://www.cnblogs.com/xingshansi/p/6702174.html 声明:本文大部分内容来自:刘建平Pi ...

  6. Mac OS平台下应用程序安装包制作工具Packages的使用介绍(补充)

    上一篇:Mac OS平台下应用程序安装包制作工具Packages的使用介绍 补充说明 上一篇文章中介绍了如何使用Packages如何创建mac下的安装包.但是这样制作出来的安装包只能安装到系统的文件路 ...

  7. 初识JS

    今儿我遇到一特别恐怖的事儿,JS 刚开始的我看到JS感觉是懵逼的,翻开第一页,感觉是棒棒哒,再看第二页,感觉是easy的,看到第三页是恐怖的,当看到的第四页的时候,我感觉今年的清明节是为我准备的 废话 ...

  8. 【微信小程序】认识微信小程序

    目前微信小程序已经支持个人版了 罗列一下微信开发的一些资料和工具 (如果你还不了解微信小程序如何操作请点击  新手教程 )里面罗列了 开发者工具 如何使用 和 微信的基本操作 很详细 一.微信开发者工 ...

  9. final修饰的变量是引用不能变还是对象的内容不能变?

    int a=1;此时a是变量: StringBuffer a=new StringBuffer();此时a就是引用变量,可以说是a引用String对象,通过a来操作String 对象 final St ...

  10. javascript 中 with 的使用

    1)简要说明         with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性.要给对象创建新的属性,必须明确地引用该对象. 2)语法格式  with(object ...