【构建动态网站—第0讲】了解传说中的“哈希表”

来源:互联网 发布:vb的感叹号 编辑:程序博客网 时间:2024/05/29 12:49

在看哈佛大学的公开课《构建动态网站》,主要是关于PHP的,在第0讲中提到了一些基本的专有名词:for-loop【for循环】, functions【函数】, methods【方法】 , hash tables【哈希表】。

 哈希表是PHP实现中尤为关键的数据结构。以下是我的总结笔记,可以从哈希算法的以下几个部分了解起:

哈希算法(散列算法):不是一个特定的算法而是一类算法的统称。一般满足关系:f(data)=key;

  • 基本概念:任意长度的data元数据,经过哈希算法处理后输出一个定长的数据key(优点:键比原值的数据量减少了,可以用这个较小的数据集来做索引,达到快速查找的目的)。
  • 将keys与原始数据进行一一映射就得到了哈希表(Hash table)。
  • 建立一对一关系明显不现实,因为输入数据不定长,而输出的哈希值却是固定长度的,那么哈希值是一个有限集合,而输入数据则可以是无穷多个。所以“碰撞”(不同的原值对应相同的哈希值)必然发生。一个成熟的哈希算法应该有较好的抗冲突性。
  • 在实现哈希表结构时要考虑哈希冲突的问题,尽量减少冲突,缩小原值(数据大)的查找范围。
  • 举两个例子:在网盘中可以利用给文件通过某种映射关系(哈希算法)赋予一个哈希码,从而达到检测文件是否与已有文件重复的作用;在电话簿中查找某人的号码,可以创建按照人名首字母顺序排列的哈希表,在首字母中查找对应的人名,存在“冲突”,但能有效地减少查找范围。
最近恰好遇到一个可以用哈希表解决的口试题,顺便和大家分享一下:
有10个会议室,每天有15-20个会议要开,每个30分钟,但它们会有一定的时间计划,但可能会有相应的调整,每个会议室都从早到晚有录像,如果我想看某个主题的会议,或者某个时间段、某天的会议,你会怎么处理?
在面试中问到视频是可以切割的,其实个人认为这个问题的主要解决点,就是如果快速地找到那个相应的视频,也就是尽量缩小查找的范围,所以可以用哈希表的思维去处理。
当天会议结束后,视频切割编号,年-月-日-开始时-分-会议室编号,比如2015年12月28日16:00在会议室9开的会议,就记为151228160009,。然后用一个表记录下编号和会议主题、主讲人等相关信息(这些项可以根据会进行搜索的项决定),也就是在编号和相关信息间建立关联。然后要查找时如果根据时间日期,就可以直接让视频编号排序查找(当然视频文件夹最好之前在处理时就应该按照一定日期范围分文件夹);如果根据相关信息,你就可以在关联表中搜寻该项,然后对应到编号上,再通过编号把视频找出来。达到一种不用打开视频去看(大数据量),直接就可以找到相应信息的视频的目的。
因为我理解更多情况是同一时间段的,比较少查找同一会议室编号的,所以会议室编号放在后面,因为只有10个会议室,所以编号里其实放不放“会议室”都可以,范围在10个也是比较小,所以“会议室编号”也可以放在信息关联表里。然后年份的话,要考虑这种情况的发生会不会超过100年,啊我想应该不会吧……所以只给了两位数。
面试的时候其实没有回答得那么具体,缺少了一些交流中的展示,有点遗憾。
其实视频不切割的话问题能不能解决,我觉得也是可以的,就是把开始时间从编号中去掉,然后一个编号(一个会议室当天的视频)对应多个会议,就是在表中,这个编号和时间唯一确定一个会议,其实这样做并不比切割视频好,因为(1)查找的主要目的往往是找到某个会议的记录,你找到的会是当天的,然后还要翻到该时间点,麻烦且数据不独立;(2)本身会议时间会发生调整,工作人员可能在记录关联信息时就要翻看视频,在那时直接分段切割并不麻烦;所以其实切割视频是优点更多的。为什么会谈到这个问题呢?因为一开始面试官没说视频是可以切割的,我想可以切割就方便多了,问了,其实是可以切割的。并且从目的上来看也本来就应该可切割。所以很多时候分析问题,一定要通过目的去确定“题意”,多问多交流,把关注点清晰化,才能更好地分析利弊,不要想当然。
当然以上都是我个人的见解,欢迎各位的批评指正。

哈希表部分参考链接:
  • 果壳问答:http://www.guokr.com/question/562532/#answer707555
推荐链接:
  • 哈佛大学公开课:构建动态网站:http://study.163.com/plan/planLearn.htm?id=1200384#/learn/resVideo?lessonId=606
  • 深入理解PHP内核:http://www.php-internals.com/book/?p=chapt03/03-01-01-hashtable
1 0
原创粉丝点击