提升工作效率利器:
Mac App Store 上的“Whale – 任务管理、时间、卡片、高效率”
状态树过滤算法又称敏感词过滤算法。
文字过滤是一般大型网站必不可少的一个功能,而且很多文字类网站更是需要。那么如何设计一个高效的文字过滤系统就是非常重要的了。
文字过滤需求简要描述:判断集合A中哪些子集属于集合B,如果用户发表一篇文章(集合A),我们需要判断这篇文章里是否存在一些关键字是属于集合B,B一般来说就是违禁词列表。
DFA
看到这里,没有接触过的同学可能会想到contains,正则之类的方法,但是很遗憾,这些方法都是行不通的,执行的效率太低。唯一比较好的算法是DFA。
DFA是中文意思就是确定型有穷状态机,英文全拼为deterministic finite automaton。
学过编译原理的同学们一定知道,在词法分析阶段将源代码中的文本变成语法的集合就是通过确定有限自动机实现的。但是DFA并不只是词法分析里用到,DFA 的用途非常的广泛,并不局限在计算机领域。本文介绍的敏感词过滤算法采用的就是DFA。
DFA的基本功能是可以通过event和当前的state得到下一个state,即event+state=nextstate。
敏感词过滤算法
在文字过滤系统中,为了能够应付较高的并发,有一个目标比较重要,就是尽量的减少计算,而在DFA中,基本没有什么计算,有的只是状态的转移。违禁的文字列表既可以用矩阵来实现,也可以用树结构来实现。比较简单的当然是用树状结构了。
如下图所示,我们将敏感词列表构造成一个状态树:
所有的文字在内存中都是unicode\ascii编码,敏感词也好还是待过滤的文本也好。如果将所有敏感词组建成一个状态树,每个树节点保存一个敏感词的一个字,从根节点往子节点延伸,如果子节点的状态是finalstate就说明是一个敏感词。如果一条路径下找敏感词失败了,要回退到失败节点,即还有分叉到其他分支的那个节点。
使用上图,我们举个例子来详细介绍一下。
1)程序启动时,将敏感词列表构建成如上图的一颗状态树。
2)如果玩家输入的聊天内容是:北京当地的。
3)程序就会沿着状态树的根节点找到根节点的第一个子节点为“北”字的节点。
4)沿着该树枝往下个节点找,找到了“京”字。因为聊天内容的当前字是“京”,表示匹配上,所以继续往下个节点找。
5)沿着该树枝的下个节点找,找到了“当”字。因为聊天内容的当前字是“当”,表示匹配上,所以继续往下个节点找。
6)沿着该树枝往下个节点找,找到了“局”字。因为聊天内容的当前字是“地”,而不是“局”,所以根据上一个节点“当”,往”当“这个节点的fail state的下个节点继续找。
7)沿着当前树枝的”当“字节点的fail state的下个节点找,找到了”地“字。因为聊天内容的当前字是”地“,表示匹配上,所以继续往该节点的下一个节点找。
8)沿着该树枝往下个节点找,找到了”的“。因为聊天内容的当前字是”的“,表示匹配上,因为”的“字节点是final state,一直找到final state节点表示找到了敏感词,根节点到 该final state节点所组成的词就是敏感词,本次找到的敏感词就是”京当地的“。
注:将敏感词列表构造成一个状态树是算法的关键所在。而构造状态树的关键所在又是fail state。
构造状态树
1)将敏感词列表里的一个敏感词拆分成一个个字,每个字作为一个节点按词的顺序挂在树的根节点,敏感词最后一个字所构成的节点赋为final state。
2)重复步骤1),以将敏感词列表里的所有敏感词都挂在树的根节点。
3)该步骤是最关键的,该步骤要为之前步骤构造好的状态树的每个节点找其fail state节点:
找fail state节点的规则是:
从树的根节点遍历树的每个节点
a)如果当前节点的父节点是根节点,那么该节点的fail state节点就是根节点。
b)否则当前节点的fail state节点就是当前节点的父节点的fail state节点的下一个节点,并且该节点的”字“和当前节点的字是同一个字。
注:一个节点的fail state节点并不一定只有一个,有可能有很多个。
今天的文章0015 状态树(敏感词)过滤算法【算法】分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/82180.html