散列表(字典)

文章目录

  • 问题
  • 散列函数
  • 应用案例
    • 将散列表用于查找
    • 防止重复
    • 将散列表用作缓存
  • 冲突
  • 性能
    • 装填因子
    • 良好的散列函数
    • 小结

问题

你在一家杂货店上班。有顾客来买东西时,你得在一个本子中查找价格。

如果本子的内容不是按字母顺序排列的,你可能为查找苹果(apple)的价格而浏览每一行,这需要很长的时间。使用的是简单查找,需要浏览每一行。时间复杂度为O(n)O(n)O(n)

如果本子的内容是按字母顺序排列的,可使用二分查找来找出苹果的价格,这需要的时间更短,为O(logn)O(log n)O(logn)

前面介绍了两种用于查找的数据结构:数组链表,为了针对上面的问题,有个更快的查找方式,引入散列表。查找时使用散列函数

散列函数

散列函数是这样的函数,即无论你给它什么数据,它都还你一个数字。用专业术语来表达的话,我们会说,散列函数“将输入映射到数字”。

需要满足的要求:

  • 单一映射,对于同样的输入,总能得到相同的输出。
  • 应将不同的输入映射到不同的数字。(可逆函数)

对于上面的问题,使用散列表来解决,首先创建一个空数组。在这个数组中存储商品价格。如苹果价格,为此,将apple作为输入交给散列函数,散列函数输出为数组索引,根据索引我们就能找到对应位置苹果的价格。

散列函数准确地指出了价格的存储位置,你根本不用查找!之所以能做到,原因有:

  • 散列函数总是将同样的输入映射到相同的索引。每次你输入avocado,得到的都是同一个数字。因此,你可首先使用它来确定将鳄梨的价格存储在什么地方,并在以后使用它来确定鳄梨的价格存储在什么地方。
  • 散列函数将不同的输入映射到不同的索引。avocado映射到索引4,milk映射到索引0。每种商品都映射到数组的不同位置,让你能够将其价格存储到这里。
  • 散列函数知道数组有多大,只返回有效的索引。如果数组包含5个元素,散列函数就不会返回无效索引100

不同于数组链表都被直接映射到内存,散列表更复杂,它使用散列函数来确定元素的存储位置。

散列表也被称为散列映射、映射、字典和关联数组。

应用案例

将散列表用于查找

创建一个话簿,每个姓名都有对应的电话号码,需要提供如下功能:

  • 添加联系人及其电话号码。
  • 通过输入联系人来获悉其电话号码。

这非常适合使用散列表来实现!在下述情况下,使用散列表是很不错的选择。

  • 创建映射。
  • 查找。

创建电话簿非常容易。首先,新建一个散列表。

phone_book = dict()

Python还提供了一种创建散列表的快捷方式——使用一对大括号。

phonr_book = { } 	#与phone_book = dict()等效

下面在电话簿中添加一些联系人的电话号码:

phone_book["jenny"] = 8675309
phone_book["emergency"] = 120

现在,假设你要查找Jenny的电话号码,为此只需向散列表传入相应的键.

>>> print phone_book["jenny"]
8675309

散列表被用于大海捞针式的查找。例如,你在访问像http://adit.io这样的网站时,计算机必须将adit.io转换为IP地址。这个过程被称为DNS解析(DNS resolution),这不是将网址映射到IP地址吗?散列表是提供这种功能的方式之一.

防止重复

假设你负责管理一个投票站。显然,每人只能投一票,但如何避免重复投票呢?有人来投票时,你询问他的全名,并将其与已投票者名单进行比对。

为此,首先创建一个散列表,用于记录已投票的人。

voted = { }

有人来投票时,检查他是否在散列表中。

value = voted.get("tom")

如果“tom”在散列表中,函数get将返回它;否则返回None。你可使用这个函数检查来投票的人是否投过票!

代码如下:

voted = {}def check_voter(name):if voted.get(name):print "kick them out!"else:voted[name] = Trueprint "let them vote!"

使用散列表来检查是否重复,速度非常快。

将散列表用作缓存

假设你访问网站facebook.com:

  1. 你向Facebook的服务器发出请求。
  2. 服务器做些处理,生成一个网页并将其发送给你。
  3. 你获得一个网页。

facebook的服务器处理需要时间,为了少做工作,提高facebook网站的访问速度,服务器使用缓存,对于经常使用的主页等,不让服务器生成它,而是将主页存储起来,在需要时直接发送给用户。缓存具有如下优点:

  • 用户能够更快地看到网页。
  • Facebook需要做的工作更少。

缓存是一种常用的加速方式,所有大型网站都使用缓存,而缓存的数据则存储在散列表中!

Facebook不仅缓存主页,还缓存About页面、Contact页面、Terms and Conditions页面等众多其他的页面。因此,它需要将页面URL映射到页面数据

当你访问Facebook的页面时,它首先检查散列表中是否存储了该页面。
代码如下:

cache = {}def get_page(url):if cache.get(url):return cache[url]else:data = get_data_from_server(url)cache[url] = datareturn data

仅当URL不在缓存中时,你才让服务器做些处理,并将处理生成的数据存储到缓存中,再返回它。这样,当下次有人请求该URL时,你就可以直接发送缓存中的数据,而不用再让服务器进行处理了。

冲突

前面讲到,散列函数最好是可逆函数,其总是将不同的键映射到数组的不同位置。实际上,几乎不可能编写出这样的散列函数。

当给两个键分配的位置相同时,就会产生冲突(collision),不同的输入得到相同的映射值。冲突很糟糕,必须要避免。处理冲突的方式很多,最简单的办法如下:如果两个键映射到了同一个位置,就在这个位置存储一个链表

  • 散列函数很重要。最理想的情况是,散列函数将键均匀地映射到散列表的不同位置。
  • 如果散列表存储的链表很长,散列表的速度将急剧下降。然而,如果使用的散列函数很好,这些链表就不会很长!

如何选择好的散列函数呢?

性能

在平均情况下,散列表的查找(获取给定索引处的值)速度与数组一样快,而插入和删除速度与链表一样快,因此它兼具两者的优点!但在最糟情况下,散列表的各种操作的速度都很慢。因此,在使用散列表时,避开最糟情况至关重要。为此,需要避免冲突。而要避免冲突,需要有:

  • 较低的填装因子;
  • 良好的散列函数。

装填因子

装填因子=散列表中包含的元素数/位置总数装填因子=散列表中包含的元素数/位置总数=/

一旦填装因子开始增大,你就需要在散列表中添加位置,这被称为调整长度(resizing)

  • 首先创建一个更长的新数组:通常将数组增长一倍。
  • 使用函数hash将所有的元素都插入到这个新的散列表中。

填装因子越低,发生冲突的可能性越小,散列表的性能越高。一个不错的经验规则是:一旦填装因子大于0.7,就调整散列表的长度。调整长度的开销很大,因此你不会希望频繁地这样做。

良好的散列函数

良好的散列函数让数组中的值呈均匀分布,糟糕的散列函数让值扎堆,导致大量的冲突。

小结

散列表是一种功能强大的数据结构,其操作速度快,还能让你以不同的方式建立数据模型。

  • 你可以结合散列函数和数组来创建散列表。
  • 冲突很糟糕,你应使用可以最大限度减少冲突的散列函数。
  • 散列表的查找、插入和删除速度都非常快。
  • 散列表适合用于模拟映射关系。
  • 一旦填装因子超过0.7,就该调整散列表的长度。
  • 散列表可用于缓存数据(例如,在Web服务器上)。
  • 散列表非常适合用于防止重复。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492527.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谁能引领国内人工智能芯片产业突围?

来源:国金证券摘要:我们认为中国在处理器/芯片领域的投资有加速的迹象,AI芯片的创业企业目前已达到40家左右。未来因人工智能边缘运算推理端和云端推理(Inferencing)芯片及设备成本,性能,耗电,效率的考量,以及各种处理器的特性不同…

OC语言知识12

本文目录 一、添加一个简单的图层二、添加一个显示图片的图层三、为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?四、UIView和CALayer的选择五、UIView和CALayer的其他关系* 上一讲已经说过,UIView内部默认…

计算机视觉介绍

1.为什么要学习图像处理和计算机视觉 计算机视觉市场需求大,其是人工智能的重要分支。 计算机视觉岗位占所有AI岗位的40%。 但是,中国高校目前尚未设置计算机视觉学科己专业;学习者众多,学习分散,缺少统一教学体系&a…

认识工业互联网

来源:智汇工业摘要:工业互联网是实现智能制造的抓手,推动工业互联网是长期的工作。工业互联网分为广义的工业互联网和狭义的工业互联网。广义的工业互联网就是第四次工业革命的代名词。和德国工业4.0以及中国制造2025类同,都是工业…

模式识别:绪论

模式识别(pattern recognition):输入原始数据并根据其类别采取相应行为的能力。 具体实例:人脸识别、语音识别、文字识别、指纹识别、DNA序列分析。 要区分不同类别的个体,需要利用其一些物理特性上的差异,成为模式分类的特征。…

A16Z内部万字报告:人类与AI结合的最佳形态

来源:36Kr摘要:人工智能技术正在快速发展,将会给我们什么样的变化?人们应该如何与人工智能相处?近日,A16Z博客上放出了一篇内部报告,介绍了人工智能将会给我们的社会带来的变化,以及…

照明与图像

光通量: 人眼所能感受到的辐射功率,等于单位时间内某一波段的辐射能量和该波段的相对视见率的乘积。单位是lm(流明)1流明 0.00146瓦 辐照度 投射到一平表面上的辐射通量密度。指到达一表面上,单位时间,单位面积上的辐射能。以…

BZOJ3434 [Wc2014]时空穿梭

摔电脑摔电脑!JZP业界毒瘤! 400题纪念~哇终于上400了的说!!!好不容易欸! 题解什么的还是Orz iwtwiioi 我求组合数的方法明明是O(n)的,为什么这么慢!!!令人报警…

图像平滑滤波

卷积与滤波概念 离散卷积 丢两个骰子,求点数加起来为 ttt 的概率是多少? 两个骰子加起来为4的概率: f(1)g(3)f(2)g(2)f(3)g(1)f(1)g(3) f(2)g(2) f(3)g(1)f(1)g(3)f(2)g(2)f(3)g(1) 写成卷积标准形式为: (f∗g)(4)∑i13f(i)g(…

fast-json.jar的用法

fast-json.jar 解析json数据:一种json数据解析方式是这种,点击这里下载jsonfast.jarfastjsonAPI文档 [{"id": 6378,"title": "test","img": "http://image.jxvdy.com/2014/0929/5428d91c9e6dc8f78fd99_0.p…

从全球制造业的迁移史,看中国制造业未来会怎么走?

来源:挖数(ID:washu66)摘要:中国制造后续如何发展?翻开全球制造业的迁移史,看是否能从中看出一点端倪。1/ 全球制造业的迁移史1/ 第一次大迁移第一次制造业大迁移发生在20世纪初,由美…

应用|5G时代10大应用场景!

来源:数字化企业摘要:5G商用日益临近,大家可曾想过5G技术未来有哪些具体的应用场景呢?作为5G领跑者的华为公司,早在2年前就出了一份白皮书,这份报告探讨了最能体现5G能力的十大应用场景。简要列表如下1.云V…

标准控件(二)——Calendar

Calendar 日程控件 属性 Borderstyle 边框样式 DayNameFormat 日标头的文本格式 FirstDayOfWeek NextPrevFormat 月导航按钮的格式 方法 DayRender() 在呈现日时激发 protected void Calendar1_DayRender(object sender,…

央行发布论文:区块链能做什么,不能做什么?

来源:悟空智能科央行发布工作论文《区块链能做什么、不能做什么?》,论文称,不要夸大或迷信区块链的功能。区块链应用要立足实际情况。目前区块链投融资领域泡沫明显。论文从经济学角度研究了区块链的功能。首先,在给出…

证明积分

证明积分:$$\int_{-\pi/2}^{\pi/2} (\sin(x))^n dx \frac{n-1}{n}\int_{-\pi/2}^{\pi/2} (\sin(x))^{n-2} dx$$ 证明: \begin{align}\int_{-\pi/2}^{\pi/2} \sin^nx \, dx& -\sin^{n-1}x \cos x\bigg|_{-\pi/2}^{\pi/2} \int_{-\pi/2}^{\pi/2} \co…

图像变换

图像变换有什么用? 图像变换意义: 图像的特征更为突出原来无法直接观测的特征直接显现出来需要提取图像中的特征,便于后续处理及图像理解 常见图像变换: 几何变换:图像放缩、图像平移、图像旋转、图像镜像、图像翻…

UVa 1225 Digit Counting

题意&#xff1a;给出n,将前n个整数顺次写在一起&#xff0c;统计各个数字出现的次数。 用的最笨的办法--直接统计-- 后来发现网上的题解有先打表来做的 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 us…

人工智能产业发展联盟公布首轮AI芯片基准评测结果,评估工具已开源

来源&#xff1a;量子位3月6日&#xff0c;由国际电信联盟、中国信息通信研究院联合主办&#xff0c;人工智能产业发展联盟&#xff08;AIIA&#xff09;和中兴通讯承办的国际论坛“AI in 5G——引领新时代论坛”在深圳召开。来自全球电信运营商、标准组织、互联网企业、设备厂…

软件工程概论第七章

面向对象分析 分析的概念主要有分析类&#xff0c;和分析活动其中分析类中的主要有实体类&#xff0c;边界类&#xff0c;和控制类。知道了分析类主要类型&#xff0c;怎样识别分析类&#xff0c;边界类通常 一个参与者和一个用例之间的交互或通信关联对应一个边界类。控制类负…

图像分割I

为什么要图像分割&#xff1f; 目标 掌握图像分割的基本概念了解图像分割方法分类 目标&#xff1a;将图像划分为不同区域定义&#xff1a;令集合R代表整个图像区域&#xff0c;对R的图像分割可以看作是将R分成N个满足以下条件的非空子集R1,R2,...,RNR_1,R_2,...,R_NR1​,R2​…