字串雜湊到整數函式,演算法
基本概念
所謂完美雜湊函式,就是指沒有衝突的雜湊函式,即對任意的 key1 != key2 有h(key1) != h(key2)。
設定義域為X,值域為Y, n=|X|,m=|Y|,那麼肯定有m>=n,如果對於不同的key1,key2屬於X,有h(key1)!=h(key2),那麼稱h為完美雜湊函式,當m=n時,h稱為最小完美雜湊函式(這個時候就是一一映射了)。
在處理大規模字串資料時,經常要為每個字串分配一個整數ID。這就需要一個字串的雜湊函式。怎麼樣找到一個完美的字串hash函式呢?
有一些常用的字串hash函式。像BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。都是比較經典的。
常用的字串Hash函式還有ELFHash,APHash等等,都是十分簡單有效的方法。這些函式使用位運算使得每一個字元都對最後的函式值產生影響。另外還有以MD5和SHA1為代表的雜湊函式,這些函式幾乎不可能找到碰撞。
常用字串雜湊函式有 BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。對於以上幾種雜湊函式,我對其進行了一個小小的評測。
Hash函式 | 資料1 | 資料2 | 資料3 | 資料4 | 資料1得分 | 資料2得分 | 資料3得分 | 資料4得分 | 平均分 |
BKDRHash | 2 | 0 | 4774 | 481 | 96.55 | 100 | 90.95 | 82.05 | 92.64 |
APHash | 2 | 3 | 4754 | 493 | 96.55 | 88.46 | 100 | 51.28 | 86.28 |
DJBHash | 2 | 2 | 4975 | 474 | 96.55 | 92.31 | 0 | 100 | 83.43 |
JSHash | 1 | 4 | 4761 | 506 | 100 | 84.62 | 96.83 | 17.95 | 81.94 |
RSHash | 1 | 0 | 4861 | 505 | 100 | 100 | 51.58 | 20.51 | 75.96 |
SDBMHash | 3 | 2 | 4849 | 504 | 93.1 | 92.31 | 57.01 | 23.08 | 72.41 |
PJWHash | 30 | 26 | 4878 | 513 | 0 | 0 | 43.89 | 0 | 21.95 |
ELFHash | 30 | 26 | 4878 | 513 | 0 | 0 | 43.89 | 0 | 21.95 |
其中資料1為100000個字母和數字組成的隨機串雜湊衝突個數。資料2為100000個有意義的英文句子雜湊衝突個數。資料3為資料1的雜湊值與 1000003(大素數)求模後儲存到線性表中衝突的個數。資料4為資料1的雜湊值與10000019(更大素數)求模後儲存到線性表中衝突的個數。
經過比較,得出以上平均得分。平均數為平方平均數。可以發現,BKDRHash無論是在實際效果還是編碼實現中,效果都是最突出的。APHash也是較為優秀的演算法。DJBHash,JSHash,RSHash與SDBMHash各有千秋。PJWHash與ELFHash效果最差,但得分相似,其演算法本質是相似的。
unsigned int SDBMHash(char *str) { unsigned int hash = 0; while (*str) { // equivalent to: hash = 65599*hash + (*str++); hash = (*str++) + (hash << 6) + (hash << 16) - hash; } return (hash & 0x7FFFFFFF); } // RS Hash Functionunsigned int RSHash(char *str) { unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; while (*str) { hash = hash * a + (*str++); a *= b; } return (hash & 0x7FFFFFFF); } // JS Hash Functionunsigned int JSHash(char *str) { unsigned int hash = 1315423911; while (*str) { hash ^= ((hash << 5) + (*str++) + (hash >> 2)); } return (hash & 0x7FFFFFFF); } // P. J. Weinberger Hash Functionunsigned int PJWHash(char *str) { unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 8); unsigned int ThreeQuarters = (unsigned int)((BitsInUnignedInt * 3) / 4); unsigned int OneEighth = (unsigned int)(BitsInUnignedInt / 8); unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnignedInt - OneEighth); unsigned int hash = 0; unsigned int test = 0; while (*str) { hash = (hash << OneEighth) + (*str++); if ((test = hash & HighBits) != 0) { hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits)); } } return (hash & 0x7FFFFFFF); } // ELF Hash Functionunsigned int ELFHash(char *str) { unsigned int hash = 0; unsigned int x = 0; while (*str) { hash = (hash << 4) + (*str++); if ((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); hash &= ~x; } } return (hash & 0x7FFFFFFF); } // BKDR Hash Functionunsigned int BKDRHash(char *str) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } // DJB Hash Functionunsigned int DJBHash(char *str) { unsigned int hash = 5381; while (*str) { hash += (hash << 5) + (*str++); } return (hash & 0x7FFFFFFF); } // AP Hash Functionunsigned int APHash(char *str) { unsigned int hash = 0; int i; for (i=0; *str; i++) { if ((i & 1) == 0) { hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3)); } else { hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5))); } } return (hash & 0x7FFFFFFF); }
程式設計珠璣中的一個hash函式
//用跟元素個數最接近的質數作為散列表的大小 #define NHASH 29989 #define MULT 31 unsigned in hash(char *p) { unsigned int h = 0; for (; *p; p++) h = MULT *h + *p; return h % NHASH; }
相關推薦
字串雜湊到整數函式,演算法
基本概念 所謂完美雜湊函式,就是指沒有衝突的雜湊函式,即對任意的 key1 != key2 有h(key1) != h(key2)。 設定義域為X,值域為Y, n=|X|,m=|Y|,那麼肯定有m>=n,如果對於不同的key1,key2屬於X,有h(key1)!=h(
python中 雜湊表應用,常見函式 MD5和SHA2演算法
通過雜湊函式計算資料儲存 insert(key, value) 插入鍵值對 get(key) 獲取值 delete(key) 刪除值 常見雜湊函式 除法雜湊:h(k) = k % m 乘法雜湊:h(k) = floor(m*(
演算法筆記_HASH字串雜湊
HASH字串雜湊的核心就是進位制轉換,轉化為十進位制整數的HASH整數雜湊,沒有什麼特別. 單純A到Z(全大寫字母)或者a到z(全小寫字母)視為26進位制. 大小寫混合視為52進位制 問題來了,大小寫混合還混上字母怎麼辦呢?有兩種想法:  
通過Java實現HMAC,將字串雜湊成為全部由字母組成的密文串
以下Java程式碼可以將任何字串通過HMAC雜湊,並輸出成由大寫的A到P組成的密文字串。 public class HMAC { private final static String KEY_MAC = "HMACMD5"; /** * 全域性陣列 *
ELFhash 字串雜湊演算法(以ELFHash詳解)
字串雜湊演算法(以ELFHash詳解) 更多字串雜湊演算法請參考:http://blog.csdn.net/AlburtHoffman/article/details/19641123 先來了解一下何為雜湊: 雜湊表是根據設定的雜湊函式H(key)和處
linux下將整數轉化為字串用法(itoa()函式,sprintf()函式)
1.1在linux系統下,沒有itoa()函式,只有atoi()函式。其中itoa()函式的標頭檔案如下:#include<stdlib.h>1.2想要實現將整數轉化為字串,可以用如下函式實現。sprintf(str,"%d",rand());//將整形變數轉換為
[SCOI2007]壓縮(動態規劃,區間dp,字串雜湊)
[SCOI2007]壓縮 狀態:設\(dp[i][j]\)表示前i個字元,最後一個\(M\)放置在\(j\)位置之後的最短字串長度. 轉移有三類,用刷表法來實現. 第一種是直接往壓縮串後面填字元,這樣就是: \[dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1)\] 另外一種
C++【模板】字串雜湊
介紹:關於字串hash,一句話概括,就是把字串有效的轉化為一個整數 hash[i]=(hash[i-1]*p+idx(s[i]))%mod for example:取p=13, mod=101,求abc對應的整數 hash[0]=1; 表示a對映1。 hash[1]=(hash[0]
51Nod1553 週期串查詢 字串 雜湊 線段樹
原文連結https://www.cnblogs.com/zhouzhendong/p/51Nod1553.html 題目傳送門 - 51Nod1553 題意 有一個串只包含數字字元。串的長度為n,下標從1開始。 有兩種操作方式: 1 l r c (1≤l≤r≤n, c是數字字元),表示將
字串雜湊--聰聰的加法等式
題目: 聰聰昨天費了九牛二虎之力終於計算出一個形如 A + B
URAL 1989(線段樹+字串雜湊)
題意:給一個字串(<=1e5), 進行操作和查詢(<=1e5)。 1)將指定位置的字元改為c 2)詢問l-r的子串,是否是迴文串。 多項式雜湊: Hash[i] = Hash[i - 1] * x + s[i](其中1 < i <= n,Has
牛客練習賽33 E. tokitsukaze and Similar String (字串雜湊)
題目連結:https://ac.nowcoder.com/acm/contest/308/E 題意:中文題 見連結 題解:雜湊預處理(三雜湊模板) 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll lon
字串雜湊 模板
模板 #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int maxn=2e4+10; const int inf=0x7ffffff; inline i
tokitsukaze and Similar String(字串雜湊)
題目連結: tokitsukaze and Similar String 題意: tokitsukaze獲得了一個長度為n (1≤n≤10^5),由a-z小寫字母組成的字串。 我們定義兩個字串是相似的,當且僅當能通過多次以下操作,使得兩個字串相等。並且把需要操
字串雜湊(詳解+模版)
參考部落格: 詳解1 詳解2 詳解3 個人理解: 字串Hash的種類還是有很多種的,不過在ACM中一般只會用到一種名為“BKDR Hash”的字串Hash演算法。它的主要思路是選取恰當的進位制,可以把字串中的字元看成一個大數字中的每一位數字。關於進位制的選擇實際上非常自由,大
牛客練習賽28 D 隨風飄(dp + 字串雜湊)
能用字串雜湊解決的問題,千萬別用字尾陣列、字典樹什麼的了…… 這題有很多個詢問,每次詢問是從n箇中拿走k個字串,問拿走之後的答案。我們顯然不能把所有拿走的方案列舉一遍,所以考慮計算每一個字串的貢獻。這裡我的貢獻指第i個字串與它前面的字串的貢獻。而這個貢獻就是
牛客國慶集訓派對Day5 H-我不愛她 (KMP+字串雜湊)
題目描述 終於活成了自己討厭的樣子。 天空仍燦爛,它愛著大海。 你喜歡大海,我愛過你。 世界上充滿了巧合。我們把每句話當成一個字串,我們定義a對b的巧合值為a的最長字尾的長度並且它是恰好是b的字首,這裡的字尾或者字首包括字串的本身。 比如字串“天空仍燦
字串雜湊[hash模板]
有這麼一類神奇的問題,給你一堆字串,然後問你有多少本質不同的字串 ~~ 或許有頭鐵的同志可以開一個map ~~ 所以有了hash大法 大致思想 我們判斷兩個字串相等,無非就是判斷他們每一位是不是相等,但是如果讓你判斷兩個數字是不是相等,是不是就簡單了許多呢?
字串雜湊+二分--poj2758Checking the Text
去年寒假講的題··· 傳送門 因為插入很少所以可以每次暴力重構 查詢就用二分+雜湊查詢lcplcplcp 好多細節···題目裡查詢的是原數列的x,yx,yx,y坑了不少人 #include<ios
leetcode 49. Group Anagrams【素數相乘處理字串雜湊】
Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate",