如何處理滾動哈希Rabin-Karp算法中的大哈希碼值?我使用模運算來避免負數,但是當哈希碼超過我的模數(N = 83559671)時會出現問題。我將我的基數設置爲素數(計算哈希碼的數字)以及模數(真的很大),但它不適用於長字符串。任何人都可以看到問題嗎?Rabin-Karp哈希碼太大
這是我的代碼。
public static void main(String [] args){
int P = 13; // base
long M = 83559671;
long iHash = 0;
String word = "abcbadccaaaabbbb";
int WINDOW = 9;
for(int i = 0; i < WINDOW; i++){
iHash = int_mod(int_mod(iHash*P, M) + word[i], M);
}
for(int i = WINDOW; i < word.length; i++){
iHash = int_mod(iHash - word[i-WINDOW] * get_pow(P, WINDOW-1, M), M);
iHash = int_mod(iHash * P, M);
iHash = int_mod(iHash + word[i], M);
}
}
public static long get_pow(int p, int t, long M){
long a = 1;
for(int i = 0 ; i < t; i++){
a = int_mod(a * p, M);
}
return a;
}
public static long int_mod(long a, long b){
return (a % b+ b) % b;
}
問題是,當我有任何字符串的長度超過8則該字符串的哈希碼超過模數83559671更長的時間,並導致一個錯誤的答案時,我做一個比較。任何較短的弦都可以正常工
爲什麼你想避免負數?如果需要,將它們視爲未簽名,但我認爲除了不可避免的2^32之外,您不需要做任何模數。 –
我正在使用Java,並且我認爲Java不支持未簽名?如果我沒有記錯,或者你的意思是BigInteger? – peter
Java的整數通常是經過簽名的,但您可以將它們視爲未簽名,並且大部分內容實際上的工作原理都是一樣的。 –