微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

移位折叠哈希生成数据库中记录的索引

如何解决移位折叠哈希生成数据库中记录的索引

我正在做一个分配,要求我实现一个移位折叠功能,以对数据库中记录的字符串类型键进行哈希处理并返回该记录在数据库中的位置。据我了解,这意味着sfold函数必须产生一个数据库中该记录的位置相匹配的哈希。

方法代码如下:

    public static long sfold(String s,int M) {
        int intLength = s.length() / 4;
        long sum = 0;
        for (int j = 0; j < intLength; j++) {
            char c[] = s.substring(j * 4,(j * 4) + 4).tochararray();
            long mult = 1;
            for (int k = 0; k < c.length; k++) {
                sum += c[k] * mult;
                mult *= 256;
            }
        }

        char c[] = s.substring(intLength * 4).tochararray();
        long mult = 1;
        for (int k = 0; k < c.length; k++) {
            sum += c[k] * mult;
            mult *= 256;
        }
        
        return (Math.abs(sum) % M);
    }

这将生成一个介于0和记录数1(M-1)之间的随机数字。问题是数字将不是唯一的,并且可能不会生成所有可能的数字。那么如何将其用于返回记录在数据库中的位置?

我的想法是从String键生成哈希,获取哈希数字,按该数字对记录进行排序,然后将其插入数据库中,但是就像我说的那样,该方法不会产生唯一的数字,因此无法保证所有数字。

解决方法

“缺乏唯一性”称为冲突,有多种解决方法。有关详细信息,请参见Wikipedia:https://en.wikipedia.org/wiki/Hash_table#Collision_resolution

主要有两种方法:

  • 单独的链接使用了额外的存储空间:如果字符串散列到表中已经存在的数字,它将溢出到辅助存储空间。在内存数据结构中,额外的存储通常是一个链表。

  • Open addressing查找未使用的空间:根据您事先确定的策略,如果字符串哈希到表中已经存在的数字,则会将其存储在同一表的其他位置。

您在这里遇到了一个非常严重的问题:

mult *= 256;

乘以2的幂表示您正在丢弃信息:仅在8个字符之后mult = 0,并且您忽略了字符串的其余部分。将乘数更改为质数(例如127)即可解决此问题。

您在这里还有另一个问题:

return (Math.abs(sum) % M);

Math.abs在特殊情况下不会返回正数:Long.MIN_VALUE。解决该问题的一种方法是在余数之后的绝对值

return Math.abs(sum % M);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。