项目目录结构如下:

其中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. Kubernetes DNS 简介

    环境 $ sudo lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16 ...

  2. APP被苹果App Store拒绝的79个原因【转】

    作为iOS开发者,估计有很多都遇到过APP提交到App Store被拒,然后这些被拒的原因多种多样,今天dApps收集了常见的被拒的原因,以便更多开发者了解. APP被苹果APPStore拒绝的各种原 ...

  3. 跟着刚哥梳理java知识点——深入理解String类(九)

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...

  4. linux(ubuntu)获取命令源码方式

    以下载ls的源码为例说明: 首先要知道ls是属于哪个包的,可以通过下面命令: #dpkg -S 'command name' 通用格式 $ dpkg -S /bin/ls 得到如下结果: coreut ...

  5. User Browsing Model简介

    搜索引擎的点击日志提供了很多有价值的query-doc相关性信息,但是这些信息是有偏的,因为对于用户没有点击过的doc,我们无法确定其是否真实地被用户浏览过.即日志中记录的展现信息与实际的展现信息之间 ...

  6. 使用Eclipse Memory Analyzer Tool(MAT)分析线上故障(一) - 视图&功能篇

    Eclipse Memory Analyzer Tool(MAT)相关文章目录: 使用Eclipse Memory Analyzer Tool(MAT)分析线上故障(一) - 视图&功能篇 使 ...

  7. 【原创】bootstrap框架的学习 第八课 -[bootstrap表单]

    Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 吹着表单或基本表单 向父 <form> 元素添加 role="form". 把标签 ...

  8. iOS APP打包分发给远程的手机测试

    APP要打包给远程的朋友或客户测试,但又不是企业账号的情况下,我们只能根据手机的udid进行描述证书的配置,再打包分发给提供了udid的手机进行安装 一.如何得到udid? 手机连接到mac电脑,打开 ...

  9. 关于Canvas Rect Transform 设置问题?

    Render Mode: Screen Space - Overlay:将UI放置在场景的上面,调节场景大小或调整分辨率,则Canvas也会随之调整. Screen Space - Camera:Ca ...

  10. C++学习 cout的格式化输出

    cout的格式化输出 1.常用: ①double 输出到小数点后n位:(保留精度 n位) #include <iostream> #include <iomanip> usin ...