Rabin-karp算法是朴素字符串匹配算法的一个特例。当字母表∑为d进制数时,即∑={0,1,2,…d-1}。如当d=10时字母表中的每个字符都是一个十进制数。我们在比较两个长度为m的子串时,可以把这两个子串当作整数进行比较,而不用逐个字符比较,从而在某种程度上减少算法时间。
把一个由d进制数字组成的字符串转换成相应的十进制整数,这是大家曾经都写过的东西,一个可能的简单实现如下:
int ConvertToInt(const char* str, int d)
{
int ans =0;
int m = strlen(str);
for(int i=0; i<m; i++)
{
ans = ans*d + str[i]-'0';
}
return ans;
}
这就是所谓的霍纳法则(Horner’s rule)
对一个长度为m的子串,求其对应的整数值,其复杂度为O(m),如果不做一些特殊的处理,每次把子串和模式P比较时,先求子串对应的整数t,再与模式P对应的整数值p比较,算法的复杂度并没有得到改进。如果用t(s)表示当前位移下子串T[s+1..s+m]的值,我们注意到把模式向右滑动一个窗口之后,下一个m位的子串T[s+2..s+m+1]对应的整数值t(s+1)和t(s)相比,只是去掉了最高位数字T[s+1],增加了一个最低位的数字T[s+m+1]。因而t(s+1)和t(s)之间有如下关系式:t(s+1)=d*(t(s)-T[s+1]*d^(m-1))&#