您的位置:首页 > 其它

白话分析字符串匹配算法——Rabin-Karp算法

2014-08-13 12:45 232 查看
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net  linuxfocus.blog.chinaunix.net

今天是《Algorithms In C》中关于字符串匹配算法中的最后一个,Rabin-Karp算法。

前面分析的KMP算法和BM算法的设计思路,都是通过前面已经比较过的字符,来对未来的匹配进行预判,实现最大的向右滑动。或者说通过这个预判,使下一次的比较更接近匹配的字符串。

而Rabin-Karp算法的设计思想也是利用前面已经匹配的字符。不过不同的是,Rabin-Karp算法不是未来这些信息去预判匹配的字符串,而是利用前面匹配字符的结果,使下一次匹配进行的更快。
——Rabin-Karp的具体实现请自行google。

为了实现这一目的,Rabin-Karp设计了一个巧妙的hash算法。首先计算pattern的hash值,然后在从sring的开头,计算相同长度字符串的hash值。若hash值相同,则表示匹配,若不同,则向右移动一位,计算新的hash值。

整个过程,与暴力的字符串匹配算法很相似,但由于计算hash值时,可以利用上一次的hash值,从而使新的hash值只需要加上新字母的计算,并减去上一次的第一个字母的计算,即可。这样相当于后面的每次匹配,只需要考虑一个新的字母,并减去一个老的字母,无疑极大的提高了效率——尤其是pattern的字符串很长的情况下。

那么这个hash是如何实现的呢?

hash(w[0 .. m-1])=(w[0]*2m-1+ w[1]*2m-2+···+ w[m-1]*20) mod q

where q is a large number.

Then, rehash(a,b,h)= ((h-a*2m-1)*2+b) mod q

上面给出这个hash的一个设计实。当不匹配时,rehash为再次hash的值,a为上次的第一个字母,b为新的字母。

参考:
1. http://igm.univ-mlv.fr/~lecroq/string/node5.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  字符串匹配