创建一个包含两个数组的哈希表

Posted

技术标签:

【中文标题】创建一个包含两个数组的哈希表【英文标题】:Create a Hash Table with two arrays 【发布时间】:2011-05-06 01:37:49 【问题描述】:

有谁知道如何做到这一点以及伪代码是什么样的?

众所周知,哈希表存储键值对,当调用键时,函数将返回与该键关联的值。我想要做的是了解创建该映射函数的底层结构。例如,如果我们生活在一个除了数组之外没有以前定义的函数的世界中,我们如何复制我们今天拥有的 Hashmap?

【问题讨论】:

你能再精确一点吗?你到底想达到什么目的?您是否针对特定语言? @romaintaz 请参阅上面的说明 【参考方案1】:

实际上,今天的一些 Hashmap 实现确实是由您建议的数组组成的。让我勾勒一下它是如何工作的:

哈希函数 哈希函数将您的键转换为第一个数组(数组 K)的索引。可以使用诸如 MD5 之类的散列函数或更简单的散列函数,通常包括模运算符。

存储桶 一个简单的基于数组的 Hashmap 实现可以使用桶来处理冲突。数组 K 中的每个元素('bucket')都包含一个数组(数组 P)对。添加或查询元素时,哈希函数会将您指向 K 中的正确存储桶,其中包含所需的数组 P。然后您遍历 P 中的元素,直到找到匹配的键,或者您在P结束。

使用哈希将键映射到存储桶 您应该确保桶的数量(即 K 的大小)是 2 的幂,比如说 2^b。要为某个键找到正确的存储桶索引,请计算 Hash(key) 但只保留前 b 位。这是转换为整数时的索引。

重新缩放 计算密钥的哈希并找到正确的存储桶非常快。但是一旦桶变得更满,您将不得不迭代越来越多的项目,然后才能找到正确的项目。所以重要的是要有足够的桶来正确分配对象,否则你的 Hashmap 会变慢。

因为您通常不知道要提前在 Hashmap 中存储多少对象,所以最好动态地扩大或缩小地图。您可以对存储的对象数量进行计数,一旦超过某个阈值,您就重新创建整个结构,但这次数组 K 的大小更大或更小。这样,K 中的一些桶是现在非常满会将它们的元素分配到几个桶中,这样性能会更好。

替代品 您也可以使用二维数组而不是数组数组,或者您可以将数组 P 交换为链表。此外,您可以简单地选择在其中一个存储桶包含的项目数量超过某个配置数量时重新创建(即重新缩放)哈希图,而不是保留存储对象的总数。

你所问的一个变体在Hash table Wikipedia entry 中被描述为“数组哈希表”。

代码 有关代码示例,请查看here。

希望这会有所帮助。

【讨论】:

【参考方案2】:

你能更准确一点吗?一个数组包含键,另一个包含值吗?

如果是这样,这里有一个 Java 示例(但这里没有这种语言的特殊性):

for (int i = 0; i < keysArray.length; i++) 
    map.put(keysArray[i], valuesArray[i]);

当然,您必须实例化您的 map 对象(如果您使用 Java,我建议使用 HashMap&lt;Object, Object&gt; 而不是过时的 HashTable),并测试您的数组以避免 @ 987654325@ 个对象并检查它们是否具有相同的大小。

【讨论】:

是的,确实,我没有看到。我已经编辑了我的答案,但主要部分并不是 Java 特有的。 我很确定他想使用两个数组创建自己的哈希表实现。 是的,我正在寻找创建自己的哈希表实现。我不想使用任何先前定义的对象。我假设我们需要一个散列函数(为值索引生成值)、两个数组(存储键和值)以及一种获取/解决冲突的方法。【参考方案3】:

示例说明:

在下面的源码中,它基本上做了两件事:

1。地图表示

一些(X 个列表)列表 X 是列表数的 2 次幂 N 是错误的。 A (2 power N)-1, or (2 power N)+1, or a prime number are good.

例子:

List myhashmap [hash_table_size];
// an array of (short) lists
// if its long lists, then there are more collisions

注意:这是数组数组,而不是两个数组(我看不到可能的通用哈希图,最好只有 2 个数组)

如果你知道算法 > 图论 > 邻接表,这个看起来一模一样。

2。哈希函数

哈希函数将字符串(输入)转换为数字(哈希值),即数组的索引

将哈希值初始化为第一个char(转换为int后) 对于每个进一步的 char,左移 4 位,然后添加 char(转换为 int 后)

例子,

int hash = input[0];
for (int i=1; i<input.length(); i++) 
    hash = (hash << 4) + input[i]


hash = hash % list.size()
// list.size() here represents 1st dimension of (list of lists)
//      that is 1st dimension size of our map representation from point #1
//      which is hash_table_size

见第一个链接:

int HTable::hash (char const * str) const

来源:http://www.relisoft.com/book/lang/pointer/8hash.htmlHow does a hash table work?

更新 这是最好的来源:http://algs4.cs.princeton.edu/34hash/

【讨论】:

【参考方案4】:

你的意思是这样的?

以下以Ruby的irb为例:

 cities = ["LA", "SF", "NY"]
 => ["LA", "SF", "NY"] 

 items = ["Big Mac", "Hot Fudge Sundae"]
 => ["Big Mac", "Hot Fudge Sundae"] 

 price = 
 =>  

 price[[cities[0], items[1]]] = 1.29
 => 1.29 

 price
 => ["LA", "Hot Fudge Sundae"]=>1.29 

 price[[cities[0], items[0]]] = 2.49
 => 2.49 

 price[[cities[1], items[0]]] = 2.99
 => 2.99 

 price
 => ["LA", "Hot Fudge Sundae"]=>1.29, ["LA", "Big Mac"]=>2.49, ["SF", "Big Mac"]=>2.99 

 price[["LA", "Big Mac"]]
 => 2.49 

【讨论】:

谢谢,但是您到底在哪里定义散列函数?据我所知,您需要一个散列函数、两个数组和一种消除冲突的方法。

以上是关于创建一个包含两个数组的哈希表的主要内容,如果未能解决你的问题,请参考以下文章

hash表原理

LeetCode389.找不同

哈希表与索引和统计

349哈希表-两个数组的交集

哈希表问题

[JavaScript 刷题] 哈希表 - 两个数组的交集 II,leetcode 350