日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

常用哈希函数的比较及其实现

發布時間:2023/12/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常用哈希函数的比较及其实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基本概念
所謂完美哈希函數。就是指沒有沖突的哈希函數。即對隨意的 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得分平均分
BKDRHash20477448196.5510090.9582.0592.64
APHash23475449396.5588.4610051.2886.28
DJBHash22497547496.5592.31010083.43
JSHash14476150610084.6296.8317.9581.94
RSHash10486150510010051.5820.5175.96
SDBMHash32484950493.192.3157.0123.0872.41
PJWHash302648785130043.89021.95
ELFHash302648785130043.89021.95

當中數據1為100000個字母和數字組成的隨機串哈希沖突個數。

?

數據2為100000個有意義的英文句子哈希沖突個數。數據3為數據1的哈希值與 1000003(大素數)求模后存儲到線性表中沖突的個數。

數據4為數據1的哈希值與10000019(更大素數)求模后存儲到線性表中沖突的個數。

經過比較。得出以上平均得分。

平均數為平方平均數。能夠發現,BKDRHash不管是在實際效果還是編碼實現中。效果都是最突出的。APHash也是較為優秀的算法。DJBHash,JSHash,RSHash與SDBMHash各有千秋。PJWHash與ELFHash效果最差,但得分相似,其算法本質是相似的。

C語言實現的hash()如下:

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 Function unsigned 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 Function unsigned int JSHash(char *str) {unsigned int hash = 1315423911;while (*str){hash ^= ((hash << 5) + (*str++) + (hash >> 2));}return (hash & 0x7FFFFFFF); }// P. J. Weinberger Hash Function unsigned 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 Function unsigned 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 Function unsigned 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 Function unsigned int DJBHash(char *str) {unsigned int hash = 5381;while (*str){hash += (hash << 5) + (*str++);}return (hash & 0x7FFFFFFF); }// AP Hash Function unsigned 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); }

上面部分參考了:https://www.cnblogs.com/yxwkf/p/5397780.html

或者使用模板的方式(C++)://6種字符串哈希算法

template<class T> size_t BKDRHash(const T * str) {register size_t hash = 0;while (size_t ch = (size_t)*str++){hash = hash * 131 + ch; // 也可以乘以31、131、1313、13131、131313.. }return hash; } template<class T> size_t SDBMHash(const T *str) {register size_t hash = 0;while (size_t ch = (size_t)*str++){hash = 65599 * hash + ch;//hash = (size_t)ch + (hash << 6) + (hash << 16) - hash; }return hash; } template<class T> size_t RSHash(const T *str) {register size_t hash = 0;size_t magic = 63689;while (size_t ch = (size_t)*str++){hash = hash * magic + ch;magic *= 378551;}return hash; } template<class T> size_t APHash(const T *str) {register size_t hash = 0;size_t ch;for (long i = 0; ch = (size_t)*str++; i++){if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash; } template<class T> size_t JSHash(const T *str) {if (!*str) // 這是由本人添加,以保證空字符串返回哈希值0 return 0;register size_t hash = 1315423911;while (size_t ch = (size_t)*str++){hash ^= ((hash << 5) + ch + (hash >> 2));}return hash; } template<class T> size_t DEKHash(const T* str) {if (!*str) // 以保證空字符串返回哈希值0 return 0;register size_t hash = 1315423911;while (size_t ch = (size_t)*str++){hash = ((hash << 5) ^ (hash >> 27)) ^ ch;}return hash; }

?

總結

以上是生活随笔為你收集整理的常用哈希函数的比较及其实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。