敏感词过滤-AC自动机
来源:互联网 发布:怪物猎人XX数据库安卓 编辑:程序博客网 时间:2024/05/18 18:42
在很多内容系统中,都需要过滤一些敏感词,比如说"fuck you shit up"就要发现里面有"fuck"、"shit"这些脏词。
首先,我们要先了解敏感词过滤的一些特征:
1. 敏感词多,一般成千上万
2. 单词长度有限,一般不会超过10
3. 要过滤的句子长度有限,一般不过1000
通过上面特征,我们粗略的算一下,如果采用暴力匹配方案的话,复杂度将会是1k*10*1k=10^7左右的运算量。
现在再考虑一下,该机制要用在什么样的系统中。如果是一个内容发布平台,每天调用次数有限,比如评论功能,不是特别频繁的,暴力匹配或许是个还不错的方案,因为简单易实现难出错:
是的,不要想太多,暴力匹配就好了。仔细想想,并发量不高,不会产生大量匹配过程,CPU不会太繁忙,暴力匹配也并不会对系统造成什么影响。
但如果是用在IM(及时消息)系统中呢?比如直播。
该类系统的特点是,在一段时间内,会同时有大量的请求。字符串处理是很耗CPU的操作,用上面暴力匹配方式的话,大量并发的请求,会不会造成大量的消息延时?
所以现在我们需要一种结构,可以存储多个字符串,并且快速匹配,最适合的莫过于Trie(字典树)了,也就是网上常说的DFA(确定有限状态机):
(不好意思,写的有点紧凑了,屏幕大小有限。)这种办法的好处很明显了,把词库数量忽略了,计算量只剩10*1k=1w了。
上面字典树的好处很明显,但也会发现一个问题,就是每次都从根上走一遍,那有没有办法呢?有,就是用AC自动机,在每个节点上多记录一个fail指针,但这种方法优化下来,最终的结果还是10*1k=1w。
这里先推荐一个AC自动机的库:https://github.com/eachain/aca,github上的一个AC自动机的库,这个库比较好玩的是Debug功能,可以把整棵树打印出来,方便调试及学习用。
好,言归正传,仔细观察会发现,fail指针指向的节点多数还不是完整的单词,这就造成了多数时候的跳转是无用的。所以上面的库优化了这一点,fail指针指向的就是一个完整的单词,这样就会把失配情况抛弃掉。但同样的,这也只是无限逼近O(1k)。
我把一个7700大小的库导入试了一下,发现大多情况是这样的:
发现了么?只有及其少数的fail指针是有指向的,翻几屏发现fail全是0的太常见了,当然这是优化过后的,如果是优化之前的,应该会多一些有指向的fail。
到现在为止,我们说的都是机械的扫描字符串的办法,会有很多误判的时候,比如“江阴毛纺厂”,不能做分词,就会误判了。但那些方法已经超出本篇范围,这里就不说了。
最后,如果大家要做敏感词过滤机制,而且可以有一定误判的情况下,建议用优化后的AC自动机,99%的情况下,时间复杂度等于串长。
- 敏感词过滤-AC自动机
- AC多模匹配算法过滤敏感词实例
- AC多模匹配算法过滤敏感词实例
- AC多模匹配算法过滤敏感词实例
- 【hdu 5880】 【AC自动机+差分法】Family View 把匹配到的敏感词改成*
- 过滤敏感词
- JAVA过滤敏感词
- 敏感词过滤算法
- web过滤敏感词
- 敏感词过滤
- php敏感词过滤
- 过滤敏感词
- 过滤敏感词
- 敏感词过滤
- 过滤敏感词,脏词
- c++敏感词过滤
- 敏感词过滤
- php过滤敏感词
- ftp上传异常
- Python列表》》》
- Linux 内存管理浅析
- Spring测试
- jsp隐含对象
- 敏感词过滤-AC自动机
- Oracle EBS OM处理销售挑库卡在待定事务处理和保留中
- SG函数
- 清除浮动8种方式
- jps使用
- Linux_tar 归档中找不到
- 鸟哥的linux私房菜--首次登录与在线求助
- h5本地存储
- Hdu3829 Cat VS Dog(最大独立点集)