散列(hash)是常用的算法思想之一,在很多程序中都会有意无意地使用到。

  先来看一个简单的问题:给出N个正整数,再给出M个正整数,问这M个数中每个数分别是否在N个数中出现过。

例如N=5,M=3,N个正整数{8,3,7,6,2},欲查询的M个正整数为{7,4,2},于是后者只有7和2在N个正整数中出现过,

而4是没有出现过的。

  对于这个问题,最直观的思路是:对每个欲查询的正整数x,遍历所有的N个数,看是否有一个数与x相等。这种

做法的时间复杂度为O(MN),当N和M都很大时,时间复杂度显然太大!

  那么该如何做呢?--不妨用空间换时间,即设定一个bool型数组hashTable[100001],其中hashTable[x]=true;表示

整数x在N中出现过,而hashTable[x]=false表示正整数x没有在N中出现过。这样就可以在一开始读入N个正整数时就进

行预处理,即当读入x时,就令hashTable[x]=true;(说明:hashTable数组需要初始化为false,表示初始状态下所有数

都没有出现过)。于是,对M个欲查询的数,就能够直接通过hashTable数组判断每个数是否出现过。显然这种做法的

时间复杂度为(N+M),代码如下:


  同样的,如果题目要求M个欲查询的数中每个数在N个数中出现的次数,那么可以把hashTable数组替换为int型,然后

在输入N个数时进行预处理,即当输入的数为x时,就令hashTable[x]++;这样就可以用O(N+M)的时间复杂度输出每个欲查询

的数出现的次数。代码如下:

  上面的问题都有一个特点,那就是直接把输入的数作为数组的下标来对这个数的性质进行统计。这是一个很好的用空间

换时间的策略,因为它将查询的复杂度降到了O(1)级别。但是,这个策略暂时还有一个问题--上面题目中的每个数都不会超过

105,因此直接作为数组下标是可行的,但是如果输入可能是109大小的整数,或者甚至是一个字符串(例如"I love you“),就不能

将它们直接作为数组下标了。要是有一种做法,可以把这些乱七八糟的元素转化为一个在能接受范围内的整数,那该多么美好呀!

  这样的做法当然是存在的,那就是散列(hash)。一般来说,散列可以浓缩成一句话”将元素通过一个函数转化为整数,使得

该整数可以尽量唯一地代表这个元素“。其中把这个转化函数称为散列函数H,也就是说,如果元素在转化前为key,那么转化后就

是一个整数H(key)。

  那么key是整数的情况来说,有哪些常用的散列函数呢?一般来说,常用的有直接定址法,平方取中法,除留余数法等

未完待续……

散列(hash)的更多相关文章

  1. StackExchange.Redis帮助类解决方案RedisRepository封装(散列Hash类型数据操作)

    本文版权归博客园和作者本人共同所有,转载和爬虫请注明本系列分享地址:http://www.cnblogs.com/tdws/p/5815735.html 上一篇文章的不合理之处,已经有所修改. 今天分 ...

  2. 散列(Hash)表入门

    一.概述 以 Key-Value 的形式进行数据存取的映射(map)结构 简单理解:用最基本的向量(数组)作为底层物理存储结构,通过适当的散列函数在词条的关键码与向量单元的秩(下标)之间建立映射关系 ...

  3. Redis散列(Hash)的相关命令

    散列 就像一个减配的Redis 内部及其类似Java的Map 内容就是key:value结构 hash类型在面向对象编程的运用中及其适合,因为它可以直接保存编程语言中的实体类关系 增 hset hse ...

  4. 非对称算法,散列(Hash)以及证书的那些事

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/35389657 作者:小马 这几个概念在金融电子支付领域用得比較多,我忽然认为把它们 ...

  5. john快速破解各种散列hash

    0x01 john工具安装: kali系统自带的有,也可以自己安装在其他linux和windows系统上,关于安装步骤网上都有可自行百度. 0x02 john常用选项 具体的其他选项可通过john - ...

  6. [No0000132]正确使用密码加盐散列[译]

    如果你是一个 web 开发工程师,可能你已经建立了一个用户账户系统.一个用户账户系统最重要的部分是如何保护密码.用户账户数据库经常被黑,如果你的网站曾经被攻击过,你绝对必须做点什么来保护你的用户的密码 ...

  7. Redis从基础命令到实战之散列类型(Hash)

    从上一篇的实例中可以看出,用字符串类型存储对象有一些不足,在存储/读取时需要进行序列化/反序列化,即时只想修改一项内容,如价格,也必须修改整个键值.不仅增大开发的复杂度,也增加了不必要的性能开销. 一 ...

  8. 线性探测再散列 建立HASH表

    根据数据元素的关键字和哈希函数建立哈希表并初始化哈希表,用开放定址法处理冲突,按屏幕输出的功能表选择所需的功能实现用哈希表对数据元素的插入,显示,查找,删除. 初始化哈希表时把elem[MAXSIZE ...

  9. PAT A1145 Hashing - Average Search Time (25 分)——hash 散列的平方探查法

    The task of this problem is simple: insert a sequence of distinct positive integers into a hash tabl ...

随机推荐

  1. js 获取函数的所有参数名

    具体思路: 利用Function.toString()方法,获取到函数的源码,再利用正则匹配获取到参数名字. 实现代码(代码基于ES6): // 获取函数的参数名 function getParame ...

  2. 视频生成 量产 win 转 linux ffmpeg linux 安装 对批量视频的尽可能短时间生成

    环境准备 Welcome to aliyun Elastic Compute Service! [root@mytest ~]# pip install baidu-aip Looking in in ...

  3. 让你彻底明白JAVA中堆与栈的区别

    原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...

  4. jsp制作登录正在加载页面.....

    1. <body style="margin:0px;"> <div id="loading"> <div class=" ...

  5. java笔记线程两种方式模拟电影院卖票

    public class SellTicketDemo { public static void main(String[] args) { // 创建三个线程对象 SellTicket st1 = ...

  6. E20171102-E

    segment   n. 环节; 部分,段落; [计算机] (字符等的) 分段; [动物学] 节片; distinct  adj. 明显的,清楚的; 卓越的,不寻常的; 有区别的; 确切的;

  7. E2017614-hm

     pluck   n. 勇气,精神; 内脏; 快而猛的拉; 〈俚〉不及格;   vt. 拔掉; 采,摘; 鼓起(勇气等); 弹(乐器);  scope  n. (处理.研究事务的) 范围; 眼界,见识 ...

  8. 使用printf和String.format格式化输出

    格式化输出 在哪些情况下使用格式化输出: 异常打印到日志中使用格式化输出有利于排查错误原因: printf格式化 示例: public class PrintfTest { public static ...

  9. 3-5 编程练习:jQuery实现简单的图片对应展示效果

    3-5 编程练习:jQuery实现简单的图片对应展示效果 通过这个章节的学习, 老师带领大家完成了一个基本的图片切换特效,接下来,我们也实现一个类似的效果,点击相应的按钮,切换对应的图片. 效果图 : ...

  10. C# 树次结构的数据

    public static void CreateTree(TreeView tv) { ///获取层次结构的数据 Tree tree = new Tree(); DataSet ds = tree. ...