为什么一般hashtable的桶数会取一个素数

设有一个哈希函数
H( c ) = c % N;
当N取一个合数时,最简单的例子是取2^n,比如说取2^3=8,这时候
H( 11100(二进制) ) = H( 28 ) = 4
H( 10100(二进制) ) = H( 20 )= 4

这时候c的二进制第4位(从右向左数)就”失效”了,也就是说,无论第c的4位取什么值,都会导致H( c )的值一样.这时候c的第四位就根本不参与H( c )的运算,这样H( c )就无法完整地反映c的特性,增大了导致冲突的几率.

取其他合数时,都会不同程度的导致c的某些位”失效”,从而在一些常见应用中导致冲突.
但是取质数,基本可以保证c的每一位都参与H( c )的运算,从而在常见应用中减小冲突几率..

(个人意见:有时候不取质数效率也不会太差..但是无疑取质数之比较保险的..)

以上就是我的理解

补充一点,这里是说在常见应用中,往往有些数据会比较相近,这时候用质数比较好,比如要存放的数据是压缩的状态,比如存储一个描述当前搜索状态的表,的这时候哈希不用质数冲突机率就比较大。

如果是随机分布的整数,那么哈希模数只要取到足够大,在概率上来说都是一样的,但是这显然脱离实际应用。

你说的情况 是比较特殊的,因为选取了比较小的一个质数,当选去大质数N时,就可以仅在N进制的某一位失效,结合计算机系统的特性,N进制位表示法往往是不关键的,而常用的2^N进制比较关键,所以可以避免冲突。

其实,偶用一些大数做过测试,用来存放一个压缩为二进制的邻接矩阵,当模数足够大时,即便是合数也能有很接近质数的效果,但在某些(几十个)合数上会造成效率严重下降,所以质数是比较保险的。

你不妨自己做实验,不要去选随机整数,而要考虑一些常见应用,用质数和合数进行测试,主要考察平均装载因子,你得到的结论可能和我一样:合数绝大多数时候效果也不错,但在一部分合数上效果差得出奇,而质数几乎全部都有很好的效果。
 
我个人认为更普遍意义的理解,如果不取素数的话是会有一定危险的,危险出现在当假设所选非素数m=x*y,如果需要hash的key正好跟这个约数x存在关系就惨了,最坏情况假设都为x的倍数,那么可以想象hash的结果为:1~y,而不是1~m。但是如果选桶的大小为素数是不会有这个问题。

为什么一般hashtable的桶数会取一个素数的更多相关文章

  1. 1001 数组中和等于K的数对 1002 数塔取数问题 1003 阶乘后面0的数量 1004 n^n的末位数字 1009 数字1的数量

    1001 数组中和等于K的数对 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K ...

  2. 51Nod 1002:数塔取数问题(DP)

    1002 数塔取数问题  基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值. 每 ...

  3. Java的8种基本数据类型的内存占用字节数和取值范围

    这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...

  4. 得到List<HashTable>里面的list然后取list的某一项

    //得到List<HashTable>里面的listUnFix然后取listUnFix判断tempfix里面得值 List<Hashtable> list = new List ...

  5. 51nod 1002 数塔取值问题 dp

    动态规划 1002 数塔取数问题 1.0 秒 131,072.0 KB 5 分 1级题   一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值. 每次只能走到下一层相邻的数上,例如 ...

  6. 取一个整数a从右端开始的4~7位

    题目:取一个整数a从右端开始的4-7位. 程序分析:可以这样考虑: (1)先使a右移4位. (2)设置一个低4位全为1,其余全为0的数.可用~(~0 < <4) (3)将上面二者进行&am ...

  7. 12--c完数/最大公约数/最小公倍数/素数/回文数

    完数/最大公约数/最小公倍数/素数/回文数 2015-04-08 10:33 296人阅读 评论(0) 收藏 举报  分类: C/C++(60)  哈尔滨工业大学(8)  版权声明:本文为博主原创文章 ...

  8. java例题_32 取一个整数a从右端开始的4~7位

    1 /*32 [程序 32 左移右移] 2 题目:取一个整数 a 从右端开始的 4-7 位. 3 */ 4 5 /*分析 6 * 从右端开始的第四位相当于原数除以1000后结果的最后一位数, 7 * ...

  9. python基础练习题(题目 取一个整数a从右端开始的4〜7位。)

    day36 --------------------------------------------------------------- 实例054:位取反.位移动 题目 取一个整数a从右端开始的4 ...

随机推荐

  1. LOJ#3104「TJOI2019」甲苯先生的字符串

    题目描述 一天小甲苯得到了一条神的指示,他要把神的指示写下来,但是又不能泄露天机,所以他要用一种方法把神的指示记下来. 神的指示是一个字符串,记为字符串 \(s_1\),\(s_1\) 仅包含小写字母 ...

  2. szwyadmin程序漏洞拿shell【方法笔记】

    我们在Google中搜索关键词 关键字:inurl:szwyadmin/login.asp 任意打开一个搜索结果,打开登录界面后在地址栏中输入下面的代码: 代码: javascript:alert(d ...

  3. 容错(Fault-tolerance)

    Spark Streaming的容错包括了三个地方的容错: 1.Executor失败容错:Executor的失败会重新启动一个新的Executor,这个是Spark自身的特性.如果Receiver所在 ...

  4. xml文件整理

    xml 97-2003 格式 \s*\n\s*\n\s*\n\s*\n\n(^个人补充信息.*)\n(.*)\n(^总成绩.*)$1$2\n$3(^个人补充信息.*)\n(.*)\n(.*)\n(^总 ...

  5. Ubuntu下彻底卸载默认安装的mysql,自己手动下载安装MYSQL

    彻底卸载: sudo apt-get autoremove --purge mysql-server-5.7 sudo apt-get remove mysql-common sudo rm -rf ...

  6. phpize是干嘛的

    安装php(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize一.phpize是干嘛的?phpize是什么东西呢?php官方的说明: ...

  7. Cogs 1708. 斐波那契平方和(矩阵乘法)

    斐波那契平方和 ★★☆ 输入文件:fibsqr.in 输出文件:fibsqr.out 简单对比 时间限制:0.5 s 内存限制:128 MB [题目描述] ,对 1000000007 取模.F0=0, ...

  8. 洛谷 4290 [HAOI2008]玩具取名 题解

    P4290 [HAOI2008]玩具取名 题目描述 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用&qu ...

  9. We found potential security vulnerabilities in your dependencies. Only the owner of this reposito...

    删除package-lock.json并同步到git 定义的依赖项./package-lock.json具有已知的安全漏洞 找到一个叫做.gitignore,把package-lock.json贴在这 ...

  10. Java 学习之路(1)第一个Java程序

    Hello World程序 在编程语言的世界里,第一个编程语言估计就是输出Hello World了吧. /** * 编写第一个Java程序,输出Hello World! * @author LJS * ...