敏感词过滤优化的解决方案

敏感词过滤优化的解决方案

介绍

敏感词字库匹配其实是关键字的一种匹配。最简单想到的额方法就是,如果要匹配某个字符串,去遍历敏感字库,这是最简单粗暴的方式。但是很明显当字库很大时,比如有六十万条数据,那么这样一个字库去遍历是非常耗时的。那么就需要我们去通过数据结构去优化匹配的方式。

暴力法和利用字典优化的方式

暴力法

直接对敏感词库进行遍历,意义对比,去全字匹配。

        static void DirectFilter(string word)
        {
            for (int i = 0; i < sensitiveArr.Length; i++)  //遍历铭感词数组
            {
                if (word == sensitiveArr[i])      //测试查找"粉丝"敏感词
                {
                    Console.WriteLine("匹配到敏感字: "+ word);
                    break;                            //匹配到之后,退出循环
                }
            }     
        }

利用字典优化的方式

核心思想,就是利用关键字去搜索。定义字典或者hashtable,kye是铭感词的首字符例如“粉”,val是所有以“粉”为首字符的敏感词组成的一个链表。这样处理之后,我们去搜索一个敏感词的时候,首先判断字典里有没有这个key,没有就直接结束,有就去遍历这个key对应的value,这样处理之后,每个敏感词可能只需要搜索几次,就能比对完,非常快。

//初始化字典
static void SensitiveDicInit()
        {
            for (int i = 0; i < sensitiveArr.Length; i++)       //遍历数组
            {
                char key = sensitiveArr[i][0];      //首字符作为Key,首字符相同的铭感词组成的链表作为valu
                if (worldsTab.ContainsKey(key))     //有key就直接add
                {
                    worldsTab[key].Add(sensitiveArr[i]);
                }
                else                                //没有就新建一个list再add
                {
                    List<string> tmpList = new List<string>();
                    tmpList.Add(sensitiveArr[i]);
                    worldsTab.Add(key, tmpList);
                }
            }
        }

        static void QuickFilter(string word) {
            char key = word[0];
            if (worldsTab.ContainsKey(key))    //查找首字符是否在字典,在就去遍历value对应的List,不在就说明不是铭感词
            {
                for (int i = 0; i < worldsTab[key].Count; i++)          //遍历value对应的List
                {
                    if (word == worldsTab[key][i])
                    {
                        Console.WriteLine("找到了对应的关键词: " + word);
                        return;
                    }
                }
                Console.WriteLine("没找到对应的关键词: " + word);
            }
            else {
                Console.WriteLine("没找到首关键字  key: " + word[0]);
            }
        }

效果

我们在入口函数里面跑一下,测试一下匹配效率。

static void Main(string[] args)
        {

            sensitiveStr = File.ReadAllText(@"d:\temp.txt");        //从文件中读取出敏感字符串
            sensitiveArr = sensitiveStr.Split(',');                 //处理成敏感词数组

            Stopwatch watch = new Stopwatch();      //时间监测类,用来检测代码执行时间ms
            watch.Start();
            DirectFilter("粉丝");
            watch.Stop();                           //结束检测
            Console.WriteLine("暴力方式匹配执行时长: " + watch.Elapsed.TotalMilliseconds);  //输出暴力法执行时间ms

            watch.Restart();
            SensitiveDicInit();
            watch.Stop();
            Console.WriteLine("字典初始化执行时长: " + watch.Elapsed.TotalMilliseconds);

            watch.Restart();
            QuickFilter("粉丝");
            watch.Stop();
            Console.WriteLine("字典方式匹配执行时长: " + watch.Elapsed.TotalMilliseconds);
            Console.ReadLine();
        }

这里是效果图
在这里插入图片描述
可以看到暴力法匹配需要9.3796ms,优化过后的方法需要15.7792ms+0.3141ms,明显是优化后的方式慢了。但是,我们可以发现只是初始化比较耗时,真正的匹配只消耗了0.3ms。所以不难发现,但敏感词库足够大时,或则说需要进行多次匹配时,后者的优势就会体现出来了。

总结

这里只是一个小小的demo,只做了全字匹配,大家如果有兴趣,其实可以加上正则表达式,去完成真正意义上的过滤敏感词。欢迎评论探讨技术,我是程序员小虎。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值