阶段三 · 哈希表和 SQRT 分解-1.3 JAVA中hashcode方法

阶段三 · 哈希表和 SQRT 分解-1.3 JAVA中hashcode方法

https://img1.sycdn.imooc.com//climg/61bd53ac09a0ea5706740193.jpg

老师,你好!

这里有一个疑问,B不能随便取吧,应该取  grade的所有组合*cls的所有组合*firstname的所有组合*lastname的所有组合吧

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
liuyubobobo 2021-12-18 13:52:01

首先,如果完全把 {grade, cls, firstName.hashCode} 当做 B 进制数看待的话,B 的取值应该是 max(grade, cls, firstName.hashCode) + 1。


比如,第一个域的取值范围是 0-3, 第二个域的取值范围是 0-10,第三个域的取值范围是 0-999。那么,1000 进制的数就可以完整表示所有这三个域的所有可能。(而不是将他们做乘法)


==========


但最重要的是,哈希值不完全是把一个对象的所有域严格当做一个 B 进制数看待,而是借用这种计算方式,计算出一个整数当做哈希值。


评判一个哈希值好坏的方式,不是他是不是一个严谨的 B 进制数,而是这样计算获得的哈希值,哈希冲突的概率的高低。(具体怎么计算这个概率,已经远超这个课程,甚至远超大多数计算机专业课程的范围了。)


在这里,我举例用 B = 31,其实是有原因的。因为在 Java 中,字符串哈希用的 B 的值,就是 31。(而很显然,字符的取值范围是超过 31 的)。


你可以尝试以下代码,其中的 my_hash() 就是用 B = 31 把 s 当做 31 进制的数字看待做计算的模拟(虽然每个域的取值可能超过 30。)。hash_code 则得到 Java 内置的字符串的哈希值。你可以看到,在短字符串下(因为这个模拟没有做溢出处理,只是一个模拟),他们的打印结果是相同的。


public class HashTest {
    
    private static long my_hash(String s){
        long res = 0;
        for(char c: s.toCharArray())
            res = res * 31 + c;
        return res;
    }
    
    public static void main(String[] args) {
        
        String s1 = "ABC";
        System.out.println(s1.hashCode());
        System.out.println(HashTest.my_hash(s1));
        
        String s2 = "imooc";
        System.out.println(s2.hashCode());
        System.out.println(HashTest.my_hash(s2));
    }
}


继续加油!:)

  • Bulu19 #1

    挖个坟,直觉上看{grade, cls, firstName.hashCode}的组合数更全面为什么还是取max(grade, cls, firstName.hashCode) + 1

    2024-11-03 20:44:40
  • liuyubobobo 回复 Bulu19 #2

    因为这个更全的组合数可能太大了,哈希表无法承受这么大的空间。这是一个取舍。实际上,如果没有空间限制,所有的哈希值都取最全的那个组合,就根本不需要哈希表的概念了。数组可以解决所有的问题。哈希表做的事情本质就是用尽量少的空间,达到数组的性能,其代价就是哈希冲突。

    2024-11-05 03:17:03
  • Bulu19 回复 liuyubobobo #3

    好的,谢谢老师

    2024-11-07 18:15:48
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
算法与数据结构
  • 参与学习       2589    人
  • 解答问题       1090    个

慕课网算法名师Liuyubobobo,5年集大成之作 从0到工作5年,算法与数据结构系统解决方案

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师