Rabin-karp 算法簡介
預處理 -- p 和 t0
字符串匹配
補救方法
RABIN-KARP-MATCHER( T,P,d,q)
1 n ← length[ T ]
2 m ← length[ P]
3 h ← d^(m-1) mod q
4 p ← 0
5 t0 ← 0
6 for i ← 1 to m Preprocessing(預處理)
7 do p ← (dp + P[i]) mod q
8 t0 ← (dt0 + T[i]) mod q
9 for s ← 0 to s-m Matching( 匹配 )
10 do if p = t
11 then if P[1..m] = T[s+1..s+m] 對p 和 T 中的每個字符進行判斷
12 then print "匹配"
13 if s < n - m
14 then t(s+1) ← (d (ts - T[s+1] h) + T[s+m+1]) mod q
*Copyright(c) Computer Science Department of XiaMen University
*
*Authored by laimingxing on: 2012年 03月 04日 星期日 18:18:28 CST
*
* @desc:
*
* @history
*/
// d = 256 ; q = 127
void RABIN_KARP_MATCHER( char *T, char *P, int q)
{
assert( T && P && q > 0 );
int M = strlen( P );
int N = strlen( T );
int i, j;
int p = 0;//hash value for pattern
int t = 0;//hash value for txt
int h = 1;
//the value of h would be "pow( d, M - 1 ) % q "
for( i = 0; i < M - 1; i++)
h = ( h * d ) % q;
for( i = 0; i < M; i++ )
{
p = ( d * p + P[i] ) % q;
t = ( d * t + T[i] ) % q;
}
//Slide the pattern over text one by one
for( i = 0; i <= N - M; i++)
{
if( p == t)
{
for( j = 0; j < M; j++)
if(T[i+j] != P[j])
break;
if( j == M )
printf("Pattern occurs with shifts: %d\n", i);
}
//Caluate hash value for next window of test:Remove leading digit,
//add trailling digit
if( i < N - M )
{
t = ( d * ( t - T[i] * h ) + T[i + M] ) % q;
if( t < 0 )
t += q;//按照書上的僞代碼會出現t爲負的情況,則之後的計算就失敗了。
}
}
}
Rabin-Karp-Matcher 的預處理時間爲 O ( m ) ,其匹配時間在最壞情況下爲 O ( ( n- m + 1) m) ,雖然 Rabin-Karp-Matcher 在最壞的情況下與樸素匹配一樣,但是實際應用中往往比樸素算法快很多,應用還是很廣的。