zoukankan      html  css  js  c++  java
  • 艾伟:一个简单的关键字过滤算法 狼人:

    早上看到老赵的《一个较完整的关键字过滤解决方案(上)》文章,讲到怎样在项目中嵌入过滤方案的问题,以及提到 xingdsumtec 两位大师发表的系列互拼的文章,在此我也忍不住谈谈自己遇到的问题以及一个的简化版的算法。

    因为过滤关键字机制到处可见,于是聪明的网友就会想到各种各样的方法突破,例如:

    1、中文会用繁体字的方法避开关键字扫描
    2、在关键字中间插入无意思的特殊字符,例如 * & # @ 等,而且个数可变
    3、使用谐音或拆字法变换关键字

    在实现自己的算法时也有些问题:

    4、随着时间推移,关键字列表会越来越大,有些论坛常用的正则表达式N次扫描的方法显得效率很低。
    5、关键字有不同的严重级别,有些需要禁止,有些只需要替换,还有一些可能记录一下即可。


    针对这些问题,可采用的应对方法:

    1、加载关键字列表时,将所有的关键字转换成繁体字一份,以扫描繁体版的关键字;
    这个转换工作只需一句就可以实现了:
    s=Microsoft.VisualBasic.Strings.StrConv(word, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, 0);

    2、在扫描原文本时,如果遇到关键字的首个文字,忽略其后的特殊字符,直到下一个有意义的文字为止,当然这里需要在定义关键字列表时指定哪些才需要这样扫描,并不是所有关键字都采用这种方式;
    例如有关键字 “你好”经常会被人输入成“你x好”或者“你xxxxx好”,那么在关键字列表里就需要定义成“你*好”,在匹配关键字时,如果遇到星号就忽略原文本下一个为特殊的字符。

    3、遇到谐音和拆字时,没什么好办法了,只好将这些谐音词和拆分词也加入到关键字列表。

    4、不用正则表达式或者 String.IndexOf方法,可以将所有关键字的首字相同的组成一个一个小组,然后在将首字放到一个散列表(HashTable/Dictionary),在扫描原文本时先在散列表里扫描,如果碰到了首字再扫描同组的关键字,这样简单处理一下效率可以提高很多。

    还有一个比用散列表更好的方法,将散列表改成一个大小为char.MaxValue的数组,然后将首个文字转成int,即char->int,然后将关键词集合放到相应下标里。这样在扫描原文本时,将被扫描的字符转成int,然后试探数组相应下标的元素是否不为NULL。这样比用散列表会更快一些。

    5、在定义关键字时,同时给一个“级别”属性,例如使用 E,R,B分别表示只记录、替换、禁止等情况。
    于是关键字的列表如下所示:
    你滚 E
    他niang的 R
    成*人*网*站 B

    这里贴一下关键的部分代码:

    Code

    完整的源代码可以在这里下载:

    http://www.uushare.com/user/csprogram/file/1132054

    源代码可能会有bug或者效率低的地方,望感兴趣的朋友请帮忙补充和改进一下。

  • 相关阅读:
    【Delphi】VCL 使用TCoolBar控件,在系统触发UAC界面时,引发CMSysFontChanged事件导致界面卡死或弹出System Error 1400错误
    【Delphi】 FMX 下 TImageList的使用方法:获取其中一张图片
    如何在电脑睡眠状态下保持程序运行
    【Delphi】使用TIdHTTPServer开发HTTP服务端在Windows2008部署后,外网无法访问
    fedora 25 virtualbox 增强功能安装
    在Win8系统中如何将一般类型的文件放在开始菜单中
    mac上的替代软件
    spring boot 1.4.1 with jsp file sample
    macbook pro 重装系统
    找不到或无法加载主类 org.codehaus.plexus.classworlds.launcher.Launcher
  • 原文地址:https://www.cnblogs.com/waw/p/2156882.html
Copyright © 2011-2022 走看看