intrabin_karp(char *T, char *P, int n, int m) { if (n < m) return-2; int h = pow(d, m-1); int p = 0; int t = 0; int i, j; for (i=0; i<m; i++) { p = (d*p + P[i]) % mod; t = (d*t + T[i]) % mod; } for (j=0; j<=n-m; j++) { if (p == t) { return j; } if (j < n-m) { t = (d*(t - h*T[j]) + T[j+m]) % mod; } } return-1; }
intmain(int argc, char *argv[]) { char t[] = "BBC ABCDAB ABCDABCDABDE"; char p[] = "ABCDABD"; int len1 = sizeof(t) - 1; int len2 = sizeof(p) - 1; int index = rabin_karp(t, p, len1, len2); printf("index: %d\n", index); return0; return0; }
现在结合上面的公式和代码再进行讲解一下。 d表示字母表的字母个数,上面的代码只接受ascii值为0~127的字符。如果采用小写英文字母来做字母表的话,那么d就是26。 h等于d^(m-1) % q。其实模q运算应该是可有可无的,加入q应该是为了避免数据溢出。但是加入模q后,由ts == p mod q不能说明ts == p,不过ts != p mod q则可以肯定ts != p。所以q最好选择比较大的质数,并且选取的q要满足使dq的值在一个计算机字长内。如果使用的是动态的编程语言的话就不用担心数据溢出,因此就不用进行模q运算。