笔记:哈希ABC(含我对字符串获得64…

      经常用hash,但从来没有自己实现过。因为我懒得自己造轮子,或者简单说:懒。
      今天想到几个关于hash的问题,通过看源代码的方式解决了,发现自己要实现一个hash也很简单啊。
   1)对于整型数据和字符串数据最常用的hash函数是啥?
   答:其实就是整数求余,hashcode=key%size。如果key不是整型怎么办?瞎搞成整型呗。(另外即使一开始是整型,也可以瞎搞一下,maybe碰撞少些)float也是4B,直接看成int就好了。double?前32位和后32位异或,搞定。字符串?复杂一点,一种做法是:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],^是n次方的意思,不是异或,31也可以替换成大一些的其他素数(如37)。
   ps:可以用Thomas Wang's 32 bit Mix Function可以对32bit的数据类型瞎搞一下,据说碰撞少些。
   2)标准库一般用哪个?开链表法还是插后面法?
   答:插后面。
   3) hash表的冗余度一般多少,是不是达不到一定的冗余度就要扩容了? 
        答:java的hash实现默认冗余最少25%,也就是如果容量100,存第76个key的时候要扩容:new一个大一倍的数组,把原来所有数据搬过来。嗯。这个代价是很高。所以如果能知道最后的数据量,最好一开始就指定一个比较合适的size。
 
      今天之所以对hash感兴趣,是突然想到不知道能不能在几十亿规模的key上运用hash。目前看来依靠标准库的实现是不行的:因为一个数组没那么大。java中数组最多有2g个元素(大概20亿),c++更少(经老猫的指点发现:64位程序可以malloc很大的数组,new不行,new总大小只能2g,不过我猜标准库中用new的可能性大些哈)。要自己实现,自己实现倒是不难。设计一下比较合理的hash函数就可以了。比如字符串的hashcode,可以用上式搞完后去除一个不大不小的素数得到double,然后直接把double看成64位整型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值