python实现dfa过滤算法_利用 DFA 算法实现文字过滤

一、DFA 算法简介

在实现文字过滤的算法中,DFA是唯一比较好的实现算法。

DFA 全称为:Deterministic Finite Automaton,即确定有穷自动机。其特征为:有一个有限状态集合和一些从一个状态通向另一个状态的边,每条边上标记有一个符号,其中一个状态是初态,某些状态是终态。但不同于不确定的有限自动机,DFA 中不会有从同一状态出发的两条边标志有相同的符号。

简单点说就是,它是是通过 event 和当前的 state 得到下一个 state,即 event + state= nextstate。理解为系统中有多个节点,通过传递进入的 event,来确定走哪个路由至另一个节点,而节点是有限的。

二、DEA 算法实践敏感词过滤

1. 敏感词库构造

以王八蛋和王八羔子两个敏感词来进行描述,首先构建敏感词库,该词库名称为SensitiveMap,这两个词的二叉树构造为:

用 hash 表构造为:

{

"王":{

"isEnd":"0",

"八":{

"羔":{

"子":{

"isEnd":"1"

},

"isEnd":"0"

},

"isEnd":"0",

"蛋":{

"isEnd":"1"

}

}

}

}

怎么用代码实现这种数据结构呢?

/**

* 读取敏感词库,将敏感词放入HashSet中,构建一个DFA算法模型

*

* @param keyWordSet 敏感词库

*/

public Map addSensitiveWordToHashMap(Set keyWordSet) {

//初始化敏感词容器,减少扩容操作

Map map = new HashMap(Math.max((int) (keyWordSet.size() / .75f) + 1, 16));

//迭代keyWordSet

for (String aKeyWordSet : keyWordSet) {

Map nowMap = map;

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

//转换成char型

char keyChar = aKeyWordSet.charAt(i);

//获取

Object wordMap = nowMap.get(keyChar);

//如果存在该key,直接赋值

if (wordMap != null) {

nowMap = (Map) wordMap;

} else { //不存在则,则构建一个map,同时将isEnd设置为0

Map newWorMap = new HashMap<>(3);

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

nowMap.put(keyChar, newWorMap);

nowMap = newWorMap;

}

//判断最后一个

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

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

}

}

}

return map;

}

2. 敏感词过滤

以上面例子构造出来的 SensitiveMap 为敏感词库进行示意,假设这里输入的关键字为:王八不好,流程图如下:

怎么用代码实现这个流程图逻辑呢?

/**

* 查找字符串中是否包含敏感字符

*

* @param txt 输入的字符串

* @return 如果存在,则返回敏感字符串;不存在,则返回空字符串

*/

public static String findSensitiveWord(String txt) {

SensitiveWordInit sensitiveWordInit = SpringContextHolder.getBean(SensitiveWordInit.class);

Map sensitiveWordMap = sensitiveWordInit.getSensitiveWordMap();

StringBuilder sensitiveWord = new StringBuilder();

// 敏感词结束标志位,表示匹配到了最后一位

boolean flag = false;

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

char word = txt.charAt(i);

// 获取指定 key

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

// 不存在,直接返回没有敏感词

if (sensitiveWordMap == null) {

break;

}

//存在,存储该敏感词,并判断是否为最后一个

sensitiveWord.append(word);

//如果为最后一个匹配规则,结束循环

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

flag = true;

break;

}

}

// 表示匹配到了完整敏感词

if (flag == true) {

return sensitiveWord.toString();

}

return "";

}

三、优化思路

对于“王*八&&蛋”这样的词,中间填充了无意义的字符来混淆,在我们做敏感词搜索时,同样应该做一个无意义词的过滤,当循环到这类无意义的字符时进行跳过,避免干扰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现DFA化简的一般步骤为: 1. 对于给定的DFA,将其状态划分为两个等价类,一个是终态集合,一个是非终态集合。 2. 将每个等价类看作一个新的状态。 3. 构造一个新的DFA,其中状态为等价类,转移函数和原DFA相同,但终态集合为新构造的状态中包含原终态集合的那些状态。 4. 对于新构造的DFA,重复步骤1-3,直到不能再进行状态的划分为止。 下面是一个利用Python实现DFA化简的示例代码: ```python def dfa_minimization(dfa): # 初始化状态划分 states = dfa.states final_states = dfa.final_states non_final_states = set(states) - set(final_states) partitions = [final_states, non_final_states] # 重复执行状态划分,直到不能再进行划分为止 while True: new_partitions = [] for partition in partitions: # 如果该等价类中只有一个状态,则不需要再划分 if len(partition) == 1: new_partitions.append(partition) continue # 根据当前等价类的状态进行划分 sub_partitions = {} for state in partition: next_state = dfa.transitions[state] next_partition = None for p in partitions: if next_state in p: next_partition = p break if next_partition not in sub_partitions: sub_partitions[next_partition] = set() sub_partitions[next_partition].add(state) # 将划分后的等价类加入新的状态划分中 for sub_partition in sub_partitions.values(): new_partitions.append(sub_partition) # 如果新的状态划分与原状态划分相同,则停止循环 if new_partitions == partitions: break else: partitions = new_partitions # 构造新的DFA new_states = [] new_transitions = {} new_final_states = set() for i, partition in enumerate(partitions): new_state = "S{}".format(i) new_states.append(new_state) for state in partition: if state in final_states: new_final_states.add(new_state) for symbol, next_state in dfa.transitions[state].items(): for j, sub_partition in enumerate(partitions): if next_state in sub_partition: new_next_state = "S{}".format(j) if new_state not in new_transitions: new_transitions[new_state] = {} new_transitions[new_state][symbol] = new_next_state return DFA(new_states, dfa.alphabet, new_transitions, "S0", new_final_states) ``` 在该代码中,`dfa`表示原始的DFA,其中包含状态、字母表、转移函数和起始状态等信息。`dfa_minimization`函数的返回值是一个新的DFA,该DFA已经化简后的。在该函数中,利用状态划分算法DFA进行了化简,并且构造了新的状态集合、转移函数和终态集合等信息。最终返回的新的DFA即为化简后的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值