最近在做项目的时候遇到了一个功能,是要检查评论和文章中敏感词,并对于这篇文章进行判断,是否做禁言处理,其中,我们有个敏感词的表,存的都是敏感词,然后我们需要对于一个帖子的正文和评论都需要进行检查,然后对于带有一定数量敏感词的帖子进行禁言或者屏蔽操作。
开始刚刚接触到这个的时候,感觉有点手足无措,但是经过万能的百度之后,发现了一个接触过的老朋友:KMP算法,这个算法呢,在软考等教材中应该是出现过的,只是没有认真的研究过,当时也就是当做一个知识点带过去了,现在发现,自己的项目和这个算法竟然有如此多的交集,可谓出来混,丢下的是迟早要还的啊。
由于本篇为简介,所以不做过多的代码方面的介绍(其实是还没有完全实现),此次只是一个简单的算法理论的介绍,如果有想要完全学习kmp的同志请浏览器返回接着百度吧。
一、什么是KMP算法
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。——百度百科
上面的说法有些官方了,其实用最最简单的话来说就是,给计算机一个最快的方法从一个名单中找到你的名字,这个时候我们用这个算法就再合适不过了。
二、一般的算法与kmp算法的区别在哪里
我们一般如果要是写一个文字匹配的算法的话,最最简单的就是用循环去匹配了,这个应该是个只要学过编程的同志都应该了解的方法,如果想要在一堆字母中找到abc的话,那么我们就需要用for去遍历详情字符,然后和这三个字母去匹配,但是这样做会有一个问题,就是,如果碰到了abd和abc相匹配的话,那么我们下一步匹配就是bdx和abc进行匹配了,匹配过了的字符会重新再比较一遍,很是浪费时间和空间。
kpm的算法是什么呢?他可以返回不匹配字符的位置,从而我们可以从不匹配的下一个位置接着进行比较,从而可以减少没有作用的匹配,举个例子,有abc和abdabc去匹配,那么当第一次匹配失败的时候,也就是abc和abd匹配的时候,这个时候返回了d的位置,那么下次进行算法的时候就是用abc和abc去匹配了,而不是用bda去和abc匹配了。
三、复杂度
说道算法不得不说的就是时间复杂度和空间复杂度,先从时间复杂度来看:
一般匹配字符串时,我们从目标字符串str(假设长度为n)的第一个下标选取和ptr长度(长度为m)一样的子字符串进行比较,如果一样,就返回开始处的下标值,不一样,选取str下一个下标,同样选取长度为n的字符串进行比较,直到str的末尾(实际比较时,下标移动到n-m)。这样的时间复杂度是O(n*m)。
KMP算法:可以实现复杂度为O(m+n)
所以KMP算法在时间复杂度上远远比一般的无脑匹配要强太多,并且是需要匹配的字符数越多,它的优势就越是明显。
至于空间复杂度嘛,因为都是在比较,只是记录了一个值的问题,所以基本上在空间复杂度上kmp算法是没有什么太大优势的。详情的情况等博主研究好了就会更新上来。