散列函数(又称哈希函数)就是在符号表中将被查找的键转化为一个数组的索引,便于键值对的查询

一、正整数的散列函数

如果所有的键都是小整数,那么可以直接将键作为数组的一个索引。

如(1,A)、(2,B)、(3,C)

除留余数法

选择大小为素数M的数组,对于任意正整数k,计算k除以M的余数,将余数作为索引值。

例如一个60人的班级的同学们的学号与姓名作为键值对

张小芳 2131469
王钢蛋 2131587
刘大皮 2131694
李好 2131447
..... ......

前两位21表示 2021年入学,第三四位31表示专业,后三位469表示编号。

直接将学号作为数组索引需要创建一个百万长度的数组去存60个人的信息过于浪费,取后三位作为索引会减少很多空间。但是长度1000的数组储存60条信息似乎还是浪费,这时可以用除留余数法。

选择大小为素数 M = 61 的数组,将每位同学学号后三位除以61得到余数如下

张小芳 42
王钢蛋 38
刘大皮 23
李好 20
... ...

取数组大小为素数 M = 61 是为了更好的分布分散,假如取 M = 100,369、469与569的余数都是69,而无法利用百位数字的信息,在选择散列函数时应尽可能地利用所有信息。当然取比60更大地素数会有更好地散列值分布,要平衡数组大小与散列值分布。

二、浮点数的散列函数

如果键是0-1之间的实数,可以将它乘以M并四舍五入得到一个(0, M-1)之间的一个整数作为索引值,但是这种情况下键的高位起的作用更大,最低位几乎没有影响。例如,M=997,两个键分别为0.10001、0.10002,通过上述方法,得到的结果都是100。最低位的1和2(加粗部分)对结果没有影响。

将浮点数的键表示为二进制数然后使用除留余数法便可消除这种影响。计算机中保存浮点数的标准是IEEE 754\854标准。IEEE 754标准详解。

32位单精度浮点数举例

如计算-9.875的散列值

首先转换为二进制形式,-1001.111,科学计数法为-1.001111✖2³。

S(符号位):该值为负所以符号位S为1;

E(指数位):指数是3,单精度偏置值是127,所以指数位为130(转换为二进制是10000010);什么是偏置值?因为指数位有可能为负,而指数位E无法表达负数,所以设置一个偏置值(,单精度为127,双精度就为1023)加上指数便是完整的指数位。如 1.01✖,指数为-8,仅靠二进制无法表达,但是有偏置值,使-8加上偏置值127等于119,119容易二进制表示1110111。偏置值相当于指数位有个初始化的值,避免其变为负数。

M(有效数字位):有效数字位指的是小数点后面的数字001111,由于其是32位单精度浮点数,所以我们要保证S+E+M有32位。S+E已经有了8位,所以M有24位,我们将有效数字001111后面加0补齐其余位数得到00111100000000000000000。最终得到一个32位的二进制整数(下图所示)11000001000111100000000000000000,转换为十进制3239968768。

3239968768即为-9.875的散列值,然后可以用除留余数法。

三、字符串的散列函数

在Java中使用UTF-16编码,UTF-16编码方式是Unicode编码方式之一(字符编码方式)。因为在UTF-16编码方式中,其基本平面占用2个字节,辅助平面占用4个字节,常见字符都是由2个字节组成,所以一个字符可以转化为一个16位整数,从而逐个提取字符将字符串转化为一个特有的数值。

Java中自带的函数如下


public static int javahash(String str) {int hash = 0;for (int i = 0; i < str.length(); i++) {hash = hash * 31 + (int)str.charAt(i);}return hash & 0x7FFFFFFF;}

四、组合键

如果键的类型含有多个整形变量,可以和String类型一样将它们混合起来。

如Date数据类型,包括day,month,year。可以用如下方式计算散列值

int hash = (((day*R+month)%M)*R+year) % M;

五、将hashCode()的值转化为一个数组索引

因为需要的是数组的索引而不是一个32位整数,现实中会将默认的hashCode()方法和除留余数法结合起来产生一个0到M-1的整数:

private int hash(Key x)
{return (x.hashCode() & 0x7fffffff) % M;//M是素数
}

六、自定义hashCode

理想的hashCode方法是能够将键平均的分散到所有可能的32位整数,也就是说对于一个任意的对象x,x.hashCode() 可以有均等的机会获得个不同整数任意一个数。Java中Integer、Double、String、URL、File对象的hashCode均能做到这一点。

例如定义一个数据类型Student

public class Student
{...private String name;private int number;private double gpa;...public int hashCode(){int hash = 17;hash = hash*31 + name.hashCode();hash = hash*31 + ((Integer)number).hashCode();//Java只有内置Integer类型的hashCode函                        //数,因此int类型需要转化为包裹类型hash = hash*31 + ((Double)gpa).hashCode();return hash;}...
}

总结

散列函数的设置是个贼拉专业的技术,我不会。。

常见数据类型的散列函数相关推荐

  1. Redis常见数据类型_Redis通用指令

    Redis常见数据类型 redis本身就是一个Map结构, 所有数据都采用key:value的形式, redis中的数据类型指的是value的类型, key部分永远是字符串 string(类似Java ...

  2. php易错,PHP学习1:几种常见数据类型及其易错点

    PHP学习1:几种常见数据类型及其易错点 (本篇随笔就是关于几种常见数据类型及其易错点,适合初学者观看,并未包含全部九种数据类型,且通篇以代码和注释的形式来呈现.) /* 双引号字符串和单引号字符串之 ...

  3. c语言中最常用的四种数据类型,计算机中有哪几种常见数据类型

    计算机中有哪几种常见数据类型 数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作.下面是YJBYS小编带来的计算机中有哪几种常见数据类型介绍,希望对你有帮助. 一.指令系统概述 指 ...

  4. date类型_Chapter 01. 常见数据类型概述 Overview of Common Data Types

    课程:DataCamp_Skill Track_SQL fundamentals[笔记] Chapter 01. 常见数据类型概述 Overview of Common Data Types 了解常见 ...

  5. 深度解析javaScript常见数据类型检查校验

    前言 在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型 基础数据类型:数字Number 字符串String 布尔Boolean Null Un ...

  6. MySQL常见数据类型(小胖虎带你了解MySQL基础知识,只为博君一关注)

    MySQL 常见数据类型 类型分类 类型 取值范围或描述 示例 整数类型 tinyint 0 -255 (长度最短) 员工年龄:32 smallint -32768-32767 员工数:2540 in ...

  7. C语言不同数据类型间的混合运算转换规则+常见数据类型

    在程序中经常会遇到不同类型的数据进行运算,若一个运算符两侧的数据类型不同,则先自动进行类型转换,使两者具有同一类型,然后进行运算,现将规律总结如下: 1. +. -. *. /运算的两个数中有一个数为 ...

  8. MySQL的基本操作指令及常见数据类型

    数据库 概念 数据库是"按照数据结构来组织.存储和管理数据的仓库".是一个长期存储在计算机内的.有组织的.可共享的.统一管理的大量数据的集合. 数据库是以一定方式储存在一起.能与多 ...

  9. Java常见数据类型举例及总结

    一.Java常见数据类型举例 1.整型 运行结果如下: 2.长整型 运行结果如下: 3.短整型 运行结果如下: 4.双精度型 运行结果如下: 注: 在电脑中,小数没有一个最精确的值,它只能精确到小数点 ...

最新文章

  1. 实验五:任意输入10个int类型数据,排序输出,再找出素数
  2. java/android 做题中整理的碎片小贴士(5)
  3. 皮一皮:好的产品营销该怎么学习?看这...
  4. Bit-Z转入GXS、PPS、SPHTX、EOS未到账解决方案
  5. c语言指针心得6,c语言指针的学习心得
  6. [设计模式] ------ 简单工厂模式
  7. ::before 和 ::after 伪元素用法
  8. 找回Win8.1(windows server 2012 R2)的双拼
  9. 智能DNS+双线机房
  10. WCF服务运行找不到X.509证书解决方案
  11. Python print()重定向 不输出到屏幕
  12. GCC编译器的安装教程(Windows环境)
  13. RTI_DDS自定义插件开发 4 接收方
  14. 二层交换机和三层交换机
  15. 同一个无线局域网(wifi)内,两台电脑无法通过ip通信
  16. Windows环境安装MySQL步骤
  17. mysql表空间查询
  18. 哪款蓝牙耳机通话效果好?蓝牙耳机通话效果最好排名
  19. vs code中文乱码
  20. oracle ebs r12 nls,Oracle EBS R12 - 如何通过命令上传XML/BI Publisher数据定义文件和模板文件...

热门文章

  1. c语言中的warn函数用法,关于c ++:MSVC等同于__attribute__((warn_unused_result))?
  2. 深度学习基础知识---梯度弥散 梯度爆炸
  3. 计算机硬件工程师需要学哪些,嵌入式硬件工程师要求是什么?需要掌握哪些内容...
  4. 配置samba服务器@手把手
  5. (转)四旋翼飞行器基本知识
  6. convariate shift(协变量 转变)
  7. 公司自用的国产API管理神器
  8. Huggingface简介及BERT代码浅析
  9. vulnhub--Thoth Tech: 1
  10. 【附源码】计算机毕业设计java在线学习交流平台设计与实现