1. 程式人生 > >Rabin-Karp ACM訓練

Rabin-Karp ACM訓練

求解問題

尋找S中T出現的位置或次數。假設S的長度為n, T的長度為m, 通過列舉S長度為m的字串的hash值與T的hash值比較。此時使用滾動hash的優化使複雜度不為O(mn). 

演算法說明

滾動hash

取兩個合適的素數b和h,假設字串C = c1c2c3c4,定義hash函式:

H(C) = (c1bm-1 + c2bm-2 + c3bm-3 + ... + cmb0) mod h

 

 其中b是基數, 相當於把字串看做b進位制。這項在計算S中m長的字串時,每向後滑動一個字元之後的字串的hash值和上一次字串的hahs值有如下關係:

H(S[k+1.. k+m]) = H(S[k..k+m-1] * b - sk

bm + sk+m)mod h

 這樣計算hash值就可以在O(n)的時間內算出S中所有位置對應的hash值,從而在O(m + n)的時間內完成字串匹配。

Hit:實際使用時取h為264,使用long long int 自然溢位省去取模時間。

PS:原始的R-K演算法還需要檢查雜湊值衝突,但這樣會使演算法複雜度退化為O(mn),比賽時只比較不檢查。

 模板

1 typedef unsinged long long int ull;