我正在尋找使用滾動散列函數,所以我可以使用非常大的字符串的n元組哈希值。Rabin-Karp字符串搜索算法中使用的滾動哈希函數是否有任何工作實現?
例如:
「計算器」,分成5克將是:
「堆」, 「tacko」, 「ackov」, 「ckove」, 「kover」, 「overf」,「verfl」,「erflo」,「rflow」
這是理想的滾動哈希函數,因爲後我計算第一n-gram中的散列,以下物質是相對便宜的計算,因爲我只需刪除第一個散列的第一個字母並添加第二個散列的新的最後一個字母。
我知道一般生成該散列函數爲:
H = c^一個的k - 1 + C 一個的k - 2 + C 一個k - 3 + ... + c k a 其中a是常數,c1,...,ck是輸入字符。
如果您點擊Rabin-Karp string search algorithm上的此鏈接,它會聲明「a」通常是一個大的素數。
我想我的哈希存儲在32位整數,所以一個素數應該有多大「a」,這樣我纔不會溢出我的整數?
是否存在這個散列函數的現有實現,我已經可以使用它了?
這裏是我創建了一個實現:
public class hash2
{
public int prime = 101;
public int hash(String text)
{
int hash = 0;
for(int i = 0; i < text.length(); i++)
{
char c = text.charAt(i);
hash += c * (int) (Math.pow(prime, text.length() - 1 - i));
}
return hash;
}
public int rollHash(int previousHash, String previousText, String currentText)
{
char firstChar = previousText.charAt(0);
char lastChar = currentText.charAt(currentText.length() - 1);
int firstCharHash = firstChar * (int) (Math.pow(prime, previousText.length() - 1));
int hash = (previousHash - firstCharHash) * prime + lastChar;
return hash;
}
public static void main(String[] args)
{
hash2 hashify = new hash2();
int firstHash = hashify.hash("mydog");
System.out.println(firstHash);
System.out.println(hashify.hash("ydogr"));
System.out.println(hashify.rollHash(firstHash, "mydog", "ydogr"));
}
}
我用101作爲我的素數。如果我的哈希溢出會影響它嗎?我認爲這是可取的,但我不確定。
這似乎是正確的方式去做這件事嗎?
爲什麼這個應用程序的主要是從「正常」的字符串哈希碼一代有什麼不同? – CPerkins 2010-02-22 21:49:17
該算法非常簡單,從僞代碼很容易實現。你試過自己編碼了嗎? – MAK 2010-02-23 20:28:37