初级5 题目一 认识哈希函数和哈希表

2023-11-16

1. 哈希函数的定义及性质:

       1)哈希函数是函数,所以接收一个变量,返回一个值,接收的变量,其定义域理论上是无穷大,返回的值是哈希值,也就是每个变量都能生成对应的哈希值

       2)哈希函数的值域是有穷的(哈希值有穷个),并非无穷大,哈希函数相当于把无穷大的范围中的所有变量映射到有穷范围中

       3)对于同一个变量,哈希函数输出的哈希值不会发生变化,例如 f(1)=0,那么把 1 重新传入 f(x),f(1) 还是 0

       4)不同变量对应的哈希值可能会相同,称为哈希碰撞。无穷映射到有穷,这一点是显然的。

       5)最重要的性质,即便会发生哈希碰撞,但如果传入很多个不同变量,其哈希值是均匀分布在值域中的,这就是哈希函数的离散性。例如输入是 0~98,输出是 0 1 2,那么每个输出基本上对应 33 个输入,这就是均匀分布。

       

       6)如果哈希函数的输入存在一定的规律性,哈希函数不会捕捉这种规律,哈希值和输入规律无关。从这个角度说,哈希函数可以打乱输入。

       7)如果哈希函数再次映射,那么映射之后的空间仍具备均匀分布的性质。例如,无穷大映射到 0~98,这是第一次映射,哈希值范围是 0~98,均匀分布。然后第二次映射,0~98 中的哈希值,每次 %3,将哈希值再次映射到 0 1 2 中,那么这个 0 1 2 上,哈希值仍然均匀分布。

2. 如何通过一个哈希函数,改出来 1000 个哈希函数?

       一个哈希函数得出来的哈希值,哈希值中的每个数都是相互独立的。例如 16 位的哈希值,每一位都相互独立。此时可将哈希值分割为前 8 位和后 8 位,前 8 位看作是 h1,后 8 位看作是 h2,新的哈希函数可借助 h1 和 和 h2 产生,比如 h1+1*h2 就是第一个哈希函数,h1 + 2*h2 就是第二个哈希函数,依次类推,且这些哈希函数仍然独立。如果不拆分哈希值,也可以找两个哈希函数,f(x) 和 g(x),之后对这两个哈希函数进行组合,f(x) + g(x),f(x) + 2g(x),依次类推,也能创造出 1000 个哈希函数。(话说,独立的两个函数线性组合,且组合函数仍然独立,这证明呢?)

       

3. 哈希表的大致逻辑

       首先创造出容量 17 的哈希表(0~16),然后传来一个 key, 这个 key 经过哈希函数的运算生成哈希值,然后哈希值 % 17,生成 0~16 上的某一个值,这个值对应的就是哈希表中的位置,此时再将 key,value 挂载到该位置上。显然,一定会发生哈希冲突,即两个 key 映射到了同一位置。解决方法是在先前的 key value 对后面接链表。例如图中 10 位置处的(A, 17)和(zuo, 31),就算利用链表连接的。

       

4. 哈希表的扩容

       首先,哈希表中的各个位置上挂载的键值对也是均匀分布的,这意味着一旦某个位置挂载的键值对数量为 h,其余位置的键值对数量也是 h 或者很接近 h。如果键值对挂载过多,哈希表的查询效率会下降,所以需要在键值对达到一定数量的情况下对哈希表进行扩容,保证其查询效率。假设某个位置键值对长度为 5 时哈希表就需要进行扩容,具体扩容步骤如下:

       

1)重新创建一个哈希表,比如 104 的容量

2)原先哈希值经过 % 17 放如原始哈希表中,现在哈希值需要经过 % 104 放入扩容的哈希表中,即每个键值对需要用哈希函数计算一次。

那为什么说哈希函数的扩容代价是 O(1) 呢?

       首先,这里说的是扩容代价,不是计算哈希函数的代价。扩容代价是指:假设数据总数为 N,从某一个容量开始,增长到 N 所需要的代价。例如从某一容量开始,每次扩容一倍,那么扩容代价就是 O(logN) (以 2 为底);如果每次扩容5倍,那么扩容代价就是 O(log(5)N) (以 5 为底)。但这样,哈希函数扩容代价仍不是 O(1)。需要注意到的一点是,扩容这件事一旦发生,在短时间内很大概率不需要进行第二次扩容,从长远角度看,扩容代价可以被压的很低。但这样也不足以说明哈希函数的扩容代价为 O(1)。

       实际上,从数学角度来说,扩容代价不可能为O(1),一定会存在扩容代价。但在实际使用时,是可以将其看做O(1)的。原因在于扩容可以离线扩容。如下图所示,左边是原始哈希表,右边是新哈希表,在用户使用时,put 和 get 操作都是在原始哈希表中进行的,即使原始哈希表此时需要扩容。而新哈希表也会将用户的 put 操作执行一遍,同时将原始哈希表中的各个值重新存入到新哈希表中。等到原始哈希表的值被新哈希表全部重新计算后,此时再将新哈希表给用户进行使用。所以对于用户来说,他读取和存入数值时,永远是O(1)操作。即便新哈希表替代了原始哈希表,但是这个替换过程用户是感受不到的,用户面对的永远是一个完整的哈希表。

       具体到各个语言时,又会有所区别,例如 JVM 中的哈希扩容。注意 JVM 中哈希结构不是桶+链表,而是桶+红黑树(平衡搜索二叉树),即相同位置处的元素都是利用红黑树连接的。

        

5. 一道经典的利用哈希函数性质的大数据题目,有个大文件 100T,其中文件每一行都是一个字符串,现在要统计整个文件中每种相同字符串的数量,如何去做?

       

       此时,需要问面试官,可以使用多少台机器,假设是 1000 台。那么此时就可以将大文件每一行的字符串进行哈希运算(%1000),放入到 1000 台机器中。哈希函数的一个重要性质是相同输入必然会产生相同输出,若某两行的字符串完全相同,则该字符串一定会分配到一台机器上,此时再在那台机器上进行统计即可。如果子机器的任务量还是太大,可以在子机器上继续利用哈希函数进行任务的分流。在大数据题目中,哈希函数用的非常多,就是因为这个性质可以将任务进行分流,相同输入必然会导致相同输出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初级5 题目一 认识哈希函数和哈希表 的相关文章

  • 正在找副业怎么找?空余时间找副业怎么找?

    很多人平时都是在企业上班 一谈到找副业 还真不知道找啥 或者就是利用空余时间去看看附近有什么临时工需求 其实这不是副业 只能算是兼职 还是靠出卖时间的廉价劳动力所得报酬的兼职 寻找合适的副业 方法主要有三个 1 从自己的主业出发 延伸出自己

随机推荐

  • 企业实施MES系统前后的10大效果对比,一文了解mes功能!

    什么是MES系统 MES信息化管理平台 包含了生产计划 采购 物流 销售 核算等模块 能够为我们带来可视化管理 可共性的管理 实施的管理等等 制造执行系统主要是针对车间级的 比如 我们可以对生产线进行实时监控 也就是说整个的生产过程监控 第
  • 概率论入门

    概率论入门 导论 概率论解决随机问题的本质 就是把局部的随机性转变为整体上的确定性 概率论的产生 能让我们对未来随机事件发生做出数学上的确定性判断 这是概率论的思想基石 概率论作为一种数学工具的基本思路 正式基于这种整体的 全局性的思考框架
  • 无理数无理性的证明问题

    问题1 求证 2 sqrt 2 不是有理数 证明 假设 2 sqrt 2 是有理数 可设 2 pq sqrt 2 frac p q p q N p 12289 q in N q gt 1 q gt 1 且 p q p 12289 q互质 则
  • 用AI给图片上色 在线将黑白照片处理成彩色照片工具(干货)

    一个在线的网址 用此工具可以给黑白照片上色 刚刚测试了一下 效果算是可以吧 图片直接进行拖拽 或者是在页面点击添加 处理后点击download即可 AI智能上色 效果看起来还不错吧 下面是测试的 图片转换地址 https imagecolo
  • timesten常见的一些简单问题

    环境为 instance name为eservice安装目录为 home timesten TimesTen 下面这些问题是针对新手而言的 通过这些问题可以帮助刚接触timesten的人可以快速配置timesten more 如何启动 ho
  • 成为优秀程序员的方法就是抛开编程?

    原文 How To Become a Better Programmer by Not Programming 作者 Jeff Atwood 我在2006年写过一篇题为 Programmers as Human Beings 程序员 亦人类
  • Python自动化操作Excel表格

    目录 一 Python打开及读取Excel表格内容 二 Python向Excel表格中写 三 批量调整字体 样式 四 编程生成Excel内图表 一 Python打开及读取Excel表格内容 打开以及读取Excel表格内容 列 column
  • 查看Google Chrome浏览器里的Cookie 文件

    文章目录 环境 步骤 扩展 chrome postman自动带入cookie 参考 平时访问各种网站查阅资料时 总是会弹框询问是否可以保存Cookie信息等 于是就好奇 看下Cookie文件存在哪里的 本文主要是基于这个问题出发 不了解co
  • MAVEN常用命令

    Maven库 http repo2 maven org maven2 Maven依赖查询 http mvnrepository com Maven常用命令 1 创建Maven的普通java项目 mvn archetype create Dg
  • Apache Derby 数据库 - 教程

    阿帕奇德比 本文介绍如何安装 Apache Derby 数据库 如何启动 Derby 服务器 如何通过 Java 连接到 Derby 以及如何使用 Derby 命令行工具发出 SQL 语句 还解释了将 Apache Derby 安装为 Wi
  • BCompare 4 key SN 亲测可用

    支持BCompare 4 2 32位 亲测可用 key w4G in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv 1BM3 H1XygMtiE0 JBgacjE9tz33sIh542
  • 《机器学习》理论——速读学习2 常用方法(3)

    机器学习 理论 速读学习2 常用方法 3 该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 time 2021 12 24 学习目标 我需要了解神经网络除了工程化部分之外的更多内容 以便于在实际有效数据中可以获得抽象
  • ArcGis Server开发Web GIS新手体验(一)

    ArcGIS Server是ESRI公司最新推出的服务器端品 主要可以实现两大功能 强大的Web GIS系统的开发 分布式GIS系统的开发 ArcGIS Server其内核与ArcGIS Desktop和ArcGIS Engine一样 都是
  • Oracle数据库中日期的操作、主键自增与分页查询

    1 oracle数据库中的日期 在Oracle数据库中 DATE类型的存储范围为公历前4712年1月1日至公历后 9999年12月31日 这个日期范围也被称为Oracle库中支持的 Gregorian calendar 尽管在实际应用中一般
  • react 事件监听

    react事件监听 在react js里监听事件很容易 需要给被监听的事件元素加上属性类似于onclick onkeydown这样的属性 例如我们现在要给title 加上点击时间的监听 class Title extends Compone
  • 懒人神器:自动生成单元测试插件 Squaretest

    你是否常常因代码需编写单元测试而痛苦不堪 你是否因单元测试历史债而惆怅不断 Squaretest或许能帮你消除痛苦消除惆怅 前言 一 Squaretest是什么 二 使用步骤 1 引入插件 2 使用步骤 总结 背景 近来公司增加了代码质量门
  • Matlab_牛顿迭代法解非线性方程

    例 用牛顿迭代法 取x初值为1 5 解算非线性方程 x 3 x 1 0 的根 程序代码 manewton m function x manewton fun dfun x0 ep N if nargin lt 5 N 500 end if
  • matlab画一个正弦函数y=sin(x)(全网最简便,没有之一)

    本博日常打卡 x 0 pi 100 2 pi y sin x plot x y plottools 说明 plottools on 按照您上次使用时的布局在当前图窗上显示图窗选项板 绘图浏览器和属性编辑器 不带参数的 plottools 与
  • live reload enabled是什么意思_老外说“Pigheaded”什么意思?猪头三?才不是

    最近 猪肉价格 一路飞涨 老妈买完菜 每天都在唠唠叨叨 今天排骨又涨了xx块钱 五花肉又涨了xx 邻居家长里短 聊得都是 猪肉 简直像小猪佩奇花一亿买了 小区热搜榜 似的 所以 小编就想着倒腾一篇 猪猪 相关的英语知识 分享给大家 咳咳 蹭
  • 初级5 题目一 认识哈希函数和哈希表

    1 哈希函数的定义及性质 1 哈希函数是函数 所以接收一个变量 返回一个值 接收的变量 其定义域理论上是无穷大 返回的值是哈希值 也就是每个变量都能生成对应的哈希值 2 哈希函数的值域是有穷的 哈希值有穷个 并非无穷大 哈希函数相当于把无穷