Hash更进一步(Hash字符串——BDKRHash)

    在这里先道歉,因为博主实在太蒻,不会写Hash冲突的解决的博客,害怕误人子弟,所以决定写一篇Hash字符串的博客来弥补,实在是罪过、罪过。

Hash字符串(第一次接触Hash的小伙伴可以去看一下我的Hash初步,仅供参考)是一种很神奇的操作,历史很多计算机专业的学者,也对它进行了一系列的探讨与开发,所以现在有很多种Hash字符串的处理方式,最为常用的有三种BKDRHash、APHash、DJBHash(这里写图片描述)等等。

有一位大佬的博客对几种常见的Hash字符串处理做了统计、实践,大家可以去他的博客看一下,反正比蒟蒻博主我的博客强太多了http://www.cnblogs.com/Stomach-ache/p/3724836.html

经过一番激烈的角逐,BDKRHash最终脱颖而出,成为了我们当之无愧的冠军。让我们有请图灵先生为它……不对,扯远了。所以今天要给大家介绍的就是BDKRHash了。

再说BDKRHash之前,先要给大家引导一下。

通常我们针对一个字符串处理,最容易想到的是将每一个字母的ASCLL码值相加得到一个字符串的Hash值。但这样做会导致我们建立的这个Hash表冲突非常多,这显然是不合理的,是一个超级烂的Hash。更进一步,大家可能会想到给每一个位置都确定一个不同的值,在用该位置上的字母的ASCLL码值 * 这个位置的固定值。这样做会有效的减小冲突,但还是不够。那么如果我们把每一个字符串的值都由它的子串 * 一个系数决定,最后在利用取余,就会更大程度避免冲突(当然也不是绝对的),这就是BDKRHash的基本思路。

BDKRHash的公式如下:
1. hashvalue[i]=(hashvalue[i-1]*seed+str[i]-'a'+1)%P
(也可以用ASCLL码值,但容易爆)
2.Hashvalue[l……r]=(hashvalue[r]-hashvlaue[l-1]*seed^(r-l+1))%P(注意第一个Hashvalue与hashvalue不同)

据某大佬说,BDKRHash的冲突在5%以内,但不是完全没有,很多时候,大家都喜欢把大P的值取int的最大值或者是long long的最大值,但是如果出题人充满心机,就很容易把你的代码卡掉。所以在写的时候尽量使用一个大的质数,例如:10^9+7和10^9+9。但也不是绝对的,这玩意儿也有可能会被卡掉。就以noip 2015模拟赛中的好文章为例。给大家看一下,出题人的心机。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值