java dfa_java 实现DFA 算法(理论百度搜索)

DFA简介

DFA全称为:Deterministic Finite Automaton,即确定有穷自动机。(自己百度吧)

直接代码:

敏感词实体类

package com.nopsmile.dfa;

public class Keywords {

private String pid;

private String Content;

public Keywords() {

}

public Keywords(String content) {

super();

Content = content;

}

public String getContent() {

return Content;

}

public void setContent(String content) {

Content = content;

}

public String getPid() {

return pid;

}

public void setPid(String pid) {

this.pid = pid;

}

}

敏感词库初始化

package com.nopsmile.dfa;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

/**

* 敏感词库初始化

*

*/

public class SensitiveWordInit{

/**

* 敏感词库

*/

public HashMap sensitiveWordMap;

/**

* 初始化敏感词 keywords

*/

public Map initKeyWord(List sensitiveWords) {

try {

// 从敏感词集合对象中取出敏感词并封装到Set集合中

Set keyWordSet = new HashSet();

for (Keywords s : sensitiveWords) {

keyWordSet.add(s.getContent().trim());

}

// 将敏感词库加入到HashMap中

addSensitiveWordToHashMap(keyWordSet);

} catch (Exception e) {

e.printStackTrace();

}

return sensitiveWordMap;

}

/**

* 封装敏感词库

*/

private void addSensitiveWordToHashMap(Set keyWordSet) {

// 初始化HashMap对象并控制容器的大小

sensitiveWordMap = new HashMap(keyWordSet.size());

// 敏感词

String key = null;

// 用来按照相应的格式保存敏感词库数据

Map nowMap = null;

// 用来辅助构建敏感词库

Map newWorMap = null;

// 使用一个迭代器来循环敏感词集合

Iterator iterator = keyWordSet.iterator();

while (iterator.hasNext()) {

key = iterator.next();

// 等于敏感词库,HashMap对象在内存中占用的是同一个地址,所以此nowMap对象的变化,sensitiveWordMap对象也会跟着改变

nowMap = sensitiveWordMap;

for (int i = 0; i < key.length(); i++) {

// 截取敏感词当中的字,在敏感词库中字为HashMap对象的Key键值

char keyChar = key.charAt(i);

// 判断这个字是否存在于敏感词库中

Object wordMap = nowMap.get(keyChar);

if (wordMap != null) {

nowMap = (Map) wordMap;

} else {

newWorMap = new HashMap();

newWorMap.put("isEnd", "0");

nowMap.put(keyChar, newWorMap);

nowMap = newWorMap;

}

// 如果该字是当前敏感词的最后一个字,则标识为结尾字

if (i == key.length() - 1) {

nowMap.put("isEnd", "1");

}

}

}

}

}

自定义的工具类

package com.nopsmile.dfa;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.Set;

import com.alibaba.fastjson.JSONArray;

import net.sf.json.JSONObject;

/**

* 敏感词过滤工具类

*

* @author AlanLee

*

*/

public class SensitivewordUtils {

/**

* 敏感词库

*/

public static Map sensitiveWordMap = null;

/**

* 只过滤最小敏感词

*/

public static int minMatchTYpe = 1;

/**

* 过滤所有敏感词

*/

public static int maxMatchType = 2;

/**

* 敏感词库敏感词数量

*

* @return

*/

public static int getWordSize() {

if (SensitivewordUtils.sensitiveWordMap == null) {

return 0;

}

return SensitivewordUtils.sensitiveWordMap.size();

}

/**

* 是否包含敏感词

*

*/

public static boolean isContaintSensitiveWord(String txt, int matchType) {

boolean flag = false;

for (int i = 0; i < txt.length(); i++) {

int matchFlag = checkSensitiveWord(txt, i, matchType);

if (matchFlag > 0) {

flag = true;

}

}

return flag;

}

/**

* 获取敏感词内容

*

* @param txt

* @param matchType

* @return 敏感词内容

*/

public static Set getSensitiveWord(String txt, int matchType) {

Set sensitiveWordList = new HashSet();

for (int i = 0; i < txt.length(); i++) {

int length = checkSensitiveWord(txt, i, matchType);

if (length > 0) {

// 将检测出的敏感词保存到集合中

sensitiveWordList.add(txt.substring(i, i + length));

i = i + length - 1;

}

}

return sensitiveWordList;

}

/**

* 替换敏感词

*

*/

public static String replaceSensitiveWord(String txt, int matchType, String replaceChar) {

String resultTxt = txt;

Set set = getSensitiveWord(txt, matchType);

Iterator iterator = set.iterator();

String word = null;

String replaceString = null;

while (iterator.hasNext()) {

word = iterator.next();

replaceString = getReplaceChars(replaceChar, word.length());

resultTxt = resultTxt.replaceAll(word, replaceString);

}

return resultTxt;

}

/**

* 替换敏感词内容

*

*/

private static String getReplaceChars(String replaceChar, int length) {

String resultReplace = replaceChar;

for (int i = 1; i < length; i++) {

resultReplace += replaceChar;

}

return resultReplace;

}

/**

* 检查敏感词数量

*

*/

public static int checkSensitiveWord(String txt, int beginIndex, int matchType) {

boolean flag = false;

// 记录敏感词数量

int matchFlag = 0;

char word = 0;

Map nowMap = SensitivewordUtils.sensitiveWordMap;

for (int i = beginIndex; i < txt.length(); i++) {

word = txt.charAt(i);

// 判断该字是否存在于敏感词库中

nowMap = (Map) nowMap.get(word);

if (nowMap != null) {

matchFlag++;

// 判断是否是敏感词的结尾字,如果是结尾字则判断是否继续检测

if ("1".equals(nowMap.get("isEnd"))) {

flag = true;

// 判断过滤类型,如果是小过滤则跳出循环,否则继续循环

if (SensitivewordUtils.minMatchTYpe == matchType) {

break;

}

}

} else {

break;

}

}

if (!flag) {

matchFlag = 0;

}

return matchFlag;

}

/**

* 敏感词汇对应个数

* 返回 "关键字"="关键字个数"

*

*/

public static Map getSensitiveWordSum(String txt, int matchType) {

Map map = new HashMap();

for (int i = 0; i < txt.length(); i++) {

int length = checkSensitiveWord(txt, i, matchType);

if (length > 0) {

// 将检测出的敏感词保存到集合中

String str=txt.substring(i, i + length);

if(map.containsKey(str)) {

map.put(str, map.get(str).intValue()+1);

}else {

map.put(str, new Integer(1));

}

//System.out.println(txt.substring(i, i + length));

i = i + length - 1;

}

}

return map;

}

/**

* 对map数组value排序,并取前10

* this method will always sort the map;

* isCondition is true condition can be used otherwise invalid

* @param unsortMap

* @return

*/

public static Map sortByValue(Map unsortMap,int condition,boolean isCondition) {

// 1. Convert Map to List of Map

List> list =

new LinkedList>(unsortMap.entrySet());

// 2. Sort list with Collections.sort(), provide a custom Comparator

// Try switch the o1 o2 position for a different order

Collections.sort(list, new Comparator>() {

public int compare(Map.Entry o1,

Map.Entry o2) {

return (o2.getValue()).compareTo(o1.getValue());

}

});

// 3. Loop the sorted list and put it into a new insertion order Map LinkedHashMap

Map sortedMap = new LinkedHashMap();

if(isCondition) {

for (int i = 0; i < list.size(); i++) {

if (i < condition) {

sortedMap.put(list.get(i).getKey(), list.get(i).getValue());

}

}

}else{

for (int i = 0; i < list.size(); i++) {

sortedMap.put(list.get(i).getKey(), list.get(i).getValue());

}

}

return sortedMap;

}

}

使用上面类流程代码

Keywords ss=new Keywords("好");

List list = new ArrayList();

list.add(ss);

SensitiveWordInit sensitiveWordInit = new SensitiveWordInit();

Map sensitiveWordMap = sensitiveWordInit.initKeyWord(list);

// 传入SensitivewordEngine类中的敏感词库

SensitivewordUtils.sensitiveWordMap = sensitiveWordMap;

SensitivewordUtils.getSensitiveWordSum("需要检测的文本", 2) ;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 程序设计: 一.DFA.javaDFA.java 中的 DFA实现成员函数 boolean recongnizeString(int move[][], int accept_state[], String word),函数功能和参数说明如下。 函数功能:如果 word 被 move 和 accept_state 所代表的 DFA 识别,则返回 true,否 则返回 false. 参数说明: 1) move[][]是状态迁移函数,move 的每一行代表一个状态,每一列代表一个输入符 号,第 0 列代表’a’,第 1 列代表’b’,……,依此类推. 例如:move ={{1,0}, {1,2}, …},则表示此 DFA 在状态 0 时,当输入为’a’时,迁移到状态 1,当输入为’b’ 时迁移到状态 0;而 DFA 在状态 1 时,当输入为’a’时,迁移到状态 1,当输入为’b’ 时迁移到状态 2. 注意:默认状态0是DFA的初始状态. 2) accept_state[]是接受状态的集合,如 accept_state[] = {2, 3},则表示状态 2 和状态 3 是接受状态. 3) word 是待识别的字符串. 注意事项: 1) 字符串 word 的长度在1到50之间. 2) move 的状态数在1到50之间,输入符号数在1到26之间. 3) 只须实现 recognizeString 函数,注意不要修改 DFA.java 文件中其它部分的内容(如 果修改了,请在提交之前改回来),更不要修改 recognizeString 的函数名,参数和 返回类型. 但可以为 DFA 类添加新的成员变量和成员函数. 4) DFA.in 文件是整个程序的输入文件,在本地机器上调试或测试程序时,可以修改 DFA.in 中的内容(用 Editplus 或记事本都可以打开修改),但遵照 DFA.in 的文件格 式. DFA.in 的格式示例如下: 4 2 ----DFA有4个状态,2个输入符号 1 0 ----接下来的 4 行 2 列代表状态迁移函数 1 2 1 3 1 0 3 ----这一行代表接收状态,若有多个用空格隔开 aaabb ----接下来的每行代表一个待识别的字符串 abbab abbaaabb abbb # ----‘#’号代表待识别的字符串到此结束 1 3 ----新的 DFA 开始,格式同上一个 DFA 0 0 0 0 cacba # 0 0 ----两个 0 代表所有输入的结束 5) 当 DFA.in 内容如 4) 时,屏幕应输出 YES NO YES NO YES

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值