早上起来刷微信,看到前同事分享了一个搜索算法的科普文章,一看遍入迷,叫做kmp算法。kmp算法可以百度一下,挺多讲的,我这里记录一下我在学习理解过程中的一些小发现,有助于简化对于该算法的程序实现过程,或者说是对理解该算法核心精髓的帮助。
kmp的核心精髓是那个匹配表的计算
原计算方式如下两个图:
kmp匹配表官方计算方式:
官方这种方式,匹配表比较简单,但是需要根据匹配失败的前缀情况对位置来查找获取匹配值。我这里想出了一个简化版的匹配表,简单来讲就是ABCABD这个字符串,匹配失败的情况下,有这么几种前缀是可能匹配成功的,都列出来:
A AB ABC ABCA ABCAB
用kmp的前后缀思路计算每种情况的匹配值,结果:
A 没有相同,长度0,得出匹配值0
AB 没有相同,长度0,得出匹配值0
ABC 没有相同,长度0,得出匹配值0
ABCA 相同的为A,长度1,得出匹配值1
ABCAB 相同的为AB,长度2,得出匹配值2
把上表保存到一个map中,key为前缀,值为匹配值。计算过程中,用匹配失败出现的情况对应的前缀类型,直接到这个map中找对应的匹配值即可,然后用前缀字符串长度减去匹配值即可获取下次的偏移量(和kmp算法后续算偏移量的方法一样)。这样程序实现起来会逻辑会简单明了一些,毕竟我认为不影响多少时效性的情况下,代码逻辑越简单越好。
其实kmp算法的核心思想就是考虑:匹配失败的情况下,成功的前缀部分中是否有重复内容,从而判断下次检索需要前进多少位,而不需要一位一位的检索,避免了一些无意义的动作,从而提升检索效率。