项目目录结构如下:

其中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. 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

    老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程   poptest是国内唯一一家培养测试开发工程师的培训机 ...

  2. hibernate的反转引擎生成两个实体类的问题

    在使用myeclipse中自带的hibernate 进行jsp开发时候遇到了这个问题.使用hibernate的反转引擎从数据库生成生成实体类,一个表生成了两个类,xx.java和xxId.java . ...

  3. 发散问题——Spring容器及加载

    一.前言 发散问题系列,是围绕日常工作,发散思考,提取问题,并寻求答案的一个系列.总的来说,就是将遇到的问题发散来提出更多的问题,并通过解决发散问题,从而对问题有更深入的了解,对知识有更深刻的记忆,帮 ...

  4. 前端代码组织优化--小demo(进阶你的思路)

    事出必有因 最近在看老项目的代码,一个富客户端的js代码,几千行的代码,全是function(){} var...的垂直布局,真的是要感动的哭了. 一开始都是这样,想实现什么功能,不管三七二十一,fu ...

  5. 图解函数重载以及arguments

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

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

  7. 怎么看iOS human interface guidelines中的user control原则

    最近离开了老东家,整理整理思路,因为一直做的是微信公众号相关的产品对app的东西有一段时间没有做过了,所以又看了一遍iOS human interface guidelines,看到user cont ...

  8. 【PAT_Basic日记】1001. 害死人不偿命的(3n+1)猜想

    还是觉得代码放这靠谱,会定期的看看和优化代码 #include <stdio.h> #include <stdlib.h> int main() { int n; int co ...

  9. C# treeview 使用笔记

    treeView默认 展开 treeView1.ExpandAll(); treeview判断点击节点: private void treeView1_AfterSelect(object sende ...

  10. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...