链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。 |
设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的算法无法比拟的,Hash链表的构造和冲突的不同实现方法对效率当然有一定的影响,然 而Hash函数是Hash链表最核心的部分,本文尝试分析一些经典软件中使用到的字符串Hash函数在执行效率、离散性、空间利用率等方面的性能问题。
作者阅读过大量经典软件原代码,下面分别介绍几个经典软件中出现的字符串Hash函数。 |
static unsigned long hashpjw(char *arKey, unsigned int nKeyLength) |
char *arEnd=arKey+nKeyLength; |
if ((g = (h & 0xF0000000))) { |
unsigned long lh_strhash(char *str) |
if (str == NULL) return(0); |
/* The following hash seems to work very well on normal text strings |
* no collisions on /usr/dict/words and it distributes on %2^n quite |
* well, not as good as MD5, but still good. |
unsigned long lh_strhash(const char *c) |
if ((c == NULL) || (*c == '/0')) |
return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); |
在下面的测量过程中我们分别将上面的两个函数标记为OpenSSL_Hash1和OpenSSL_Hash2,至于上面的实现中使用MD5算法的实现函数我们不作测试。 |
#ifndef NEW_HASH_FUNCTION |
/* Calc hashvalue for a key */ |
static uint calc_hashnr(const byte *key,uint length) |
register uint nr=1, nr2=4; |
nr^= (((nr & 63)+nr2)*((uint) (uchar) *key++))+ (nr << 8); |
/* Calc hashvalue for a key, case indepenently */ |
static uint calc_hashnr_caseup(const byte *key,uint length) |
register uint nr=1, nr2=4; |
nr^= (((nr & 63)+nr2)*((uint) (uchar) toupper(*key++)))+ (nr << 8); |
* The basis of the hash algorithm was taken from an idea sent by email to the |
* IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and |
* Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com) |
* later improved on their algorithm. |
* The magic is in the interesting relationship between the special prime |
* 16777619 (2^24 + 403) and 2^32 and 2^8. |
* This hash produces the fewest collisions of any function that we've seen so |
* far, and works well on both numbers and strings. |
uint calc_hashnr(const byte *key, uint len) |
for (hash = 0; key < end; key++) |
hash ^= (uint) *(uchar*) key; |
uint calc_hashnr_caseup(const byte *key, uint len) |
for (hash = 0; key < end; key++) |
hash ^= (uint) (uchar) toupper(*key); |
Mysql中对字符串Hash函数还区分了大小写,我们的测试中使用不区分大小写的字符串Hash函数,另外我们将上面的两个函数分别记为MYSQL_Hash1和MYSQL_Hash2。 |
unsigned int hash(char *str) |
register unsigned char *p; |
for(h=0, p = (unsigned char *)str; *p ; p++) |
从上面给出的经典字符串Hash函数中可以看出,有的涉及到字符串大小敏感问题,我们的测试中只考虑字符串大小写敏感的函数,另外在上面的函数中有的函数需要长度参数,有的不需要长度参数,这对函数本身的效率有一定的影响,我们的测试中将对函数稍微作一点修改,全部使用长度参数,并将函数内部出现的计算长度代码删除。 |
我们用来作测试用的Hash链表采用经典的拉链法解决冲突,另外我们采用静态分配桶(Hash链表长度)的方法来构造Hash链表,这主要是为了简化我们的实现,并不影响我们的测试结果。 |
测试文本采用单词表,测试过程中从一个输入文件中读取全部不重复单词构造一个Hash表,测试内容分别是函数总调用次数、函数总调用时间、最大拉链长度、 平均拉链长度、桶利用率(使用过的桶所占的比率),其中函数总调用次数是指Hash函数被调用的总次数,为了测试出函数执行时间,该值在测试过程中作了一 定的放大,函数总调用时间是指Hash函数总的执行时间,最大拉链长度是指使用拉链法构造链表过程中出现的最大拉链长度,平均拉链长度指拉链的平均长度。 |
PIII600笔记本,128M内存,windows 2000 server操作系统。 |
以下分别是对两个不同文本文件中的全部不重复单词构造Hash链表的测试结果,测试结果中函数调用次数放大了100倍,相应的函数调用时间也放大了100倍。 |
分享到:
相关推荐
字符串哈希算法和内存监控类,暂时放一下,还在开发中
list some String Hash algorithm, you can use it directly.
将字符串哈希成数字的几种经典的方法:其中的一部分 #ifndef INCLUDE_GENERALHASHFUNCTION_C_H #define INCLUDE_GENERALHASHFUNCTION_C_H #include typedef unsigned int (*hash_function)(char*, unsigned int...
玩ACM的可以下载去看看,相信对你会有帮助的。 hash KMP 字典树 AC自动机 后缀数组 很全的字符串处理算法
MySQL分库分表,读写分离与Mycat的使用文章中字符串hash解析算法分片sql
C#实现字符串SHA-256加密算法,非常好用,供大家学习参考。
性能很高的计算字符串或文件hash值的函数,比md5速度快得多,自己一直用着,重复的几率为很底,一般的应用足够, var I64BIT_TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-'.split...
本文介绍了目前主流的一些字符串哈希算法,能够对开发过程中的一些针对字符串的哈希结构有指导作用
字符串匹配算法(模式搜索 Pattern Search)的应用于包括但不限于:生物信息学、信息检索、拼写检查、语言翻译、数据压缩、网络入侵检测、论文查重等等等等。字符串匹配算法,就是在一个字符串text中查找是否存在一...
其中只有一个thomas wang 的整数hash 算法,其余都是字符串的hash算法。
Hash函数数据1数据2数据3数据4数据1得分数据2得分数据3得分数据4得分平均分BKDRHash20477448196.5510090.9582.0592.6
支持对文件和字符串计算MD5值.本程序算法使用C++语言.可以快速计算出文件或字符串得md5值,程序简捷明了
/简单的字符串hash/unsigned int hash = 0;return (hash & 0x7FFFFFFF);
下面小编就为大家带来一篇常用Hash算法(C语言的简单实现)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
经测试,在2500万内随机字符串转成的数字,没有发生碰撞。这个办法可以满足需要。 public static ulong MakeNumber(string source) { var mk = new System.Security.Cryptography.MD5CryptoServiceProvider();...
各种数的hash算法,包括整数,浮点数,字符串等
geohash基本原理是将地球理解为一个二维平面,将平面递归分解成更小的子块,每个子块在一定经纬度范围内拥有相同的编码。GeoHash将二维的经纬度转换成一维的字符串。