经常使用哈希函数的比較及其C语言实现
基本概念
所谓完美哈希函数。就是指没有冲突的哈希函数。即对随意的 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 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);
}
编程珠玑中的一个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;
}
经常使用哈希函数的比較及其C语言实现的更多相关文章
- 字符串哈希函数(String Hash Functions)
哈希函数举例 http://www.cse.yorku.ca/~oz/hash.html Node.js使用的哈希函数 https://www.npmjs.org/package/string-has ...
- lintcode:哈希函数
题目: 哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...
- Eight(bfs+全排列的哈希函数)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22207 Accepted: 9846 Special Judge ...
- 算法初级面试题05——哈希函数/表、生成多个哈希函数、哈希扩容、利用哈希分流找出大文件的重复内容、设计RandomPool结构、布隆过滤器、一致性哈希、并查集、岛问题
今天主要讨论:哈希函数.哈希表.布隆过滤器.一致性哈希.并查集的介绍和应用. 题目一 认识哈希函数和哈希表 1.输入无限大 2.输出有限的S集合 3.输入什么就输出什么 4.会发生哈希碰撞 5.会均匀 ...
- lintcode-->哈希函数
在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基 ...
- php的哈希函数
哈希函数: echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n"; 验证函数: boolean ...
- djb2:一个产生简单的随机分布的哈希函数
目录 LCG算法 示例代码 djb2 示例代码 为什么选择参数33和 33 was chosen because: 5381 was chosen because 哈希选择参考 LCG算法 djb2与 ...
- lintcode-128-哈希函数
128-哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...
- Java集合(八)哈希表及哈希函数的实现方式
Java集合(八)哈希表及哈希函数的实现方式 一.哈希表 非哈希表的特点:关键字在表中的位置和它之间不存在一个确定的关系,查找的过程为给定值一次和各个关键字进行比较,查找的效率取决于和给定值进行比较的 ...
随机推荐
- 网络协议之TCP
前言 近年来,随着信息技术的不断发展,各行各业也掀起了信息化浪潮,为了留住用户和吸引用户,各个企业力求为用户提供更好的信息服务,这也导致WEB性能优化成为了一个热点.据分析,网站速度越快,用户的黏性. ...
- HTML网页自动跳转
<meta http-equiv="refresh" content="3;URL=res.html">
- 配置sql server 2000以允许远程访问
配置sql server 2000以允许远程访问适合故障:1. 用sql企业管理器能访问sql server 2000(因为它是采用命名管道(named pipes)方式进行方式),但用ado.net ...
- Knockout.Js官网学习(模版绑定)
模板绑定器 如今页面结构越来越复杂,仅仅依靠foreach已经不足以我们的使用,这个时候我们就需要模板的存在,模板的优点自然很多,首先会让页面整洁,同时修改起来也可以方面的定位,最重要的是ko可以条件 ...
- CVE-2013-0025
Microsoft IE ‘SLayoutRun’释放后重用漏洞(CNNVD-201302-197) Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WE ...
- 一步一步学习IdentityServer4 (5) .NETCore2.0 Swagger
首先添加nuget: Swashbuckle.AspNetCore services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new ...
- IIS部署asp.net MVC 出现错误 403.14-Forbidden解决办法
可能性一: <system.webServer> <validationvalidateIntegratedModeConfiguration="false" ...
- js 获取时间戳的方法
(new Date()).valueOf()1541569364658(new Date()).getTime()1541569372623Number(new Date())154156938662 ...
- USACO 5.2 Snail Trails
Snail TrailsAll Ireland Contest Sally Snail likes to stroll on a N x N square grid (1 <n <= 12 ...
- poj2387 Til the Cows Come Home(Dijkstra)
题目链接 http://poj.org/problem?id=2387 题意 有n个路标,编号1~n,输入路标编号及路标之间相隔的距离,求从路标n到路标1的最短路径(由于是无向图,所以也就是求从路标1 ...