algorithm - 将域中的一组整数散列到一组桶中

标签 algorithm hash

假设我有一组介于 1-100 之间的整数。我只会从帽子里抽出 5 个这样的整数。然后我想将这 5 个整数放入保证唯一的 5 个桶中(无需重复数据删除或使用类似 quadratic probing 的任何东西)。想知道如何做到这一点。

例如,假设我有这些数字(从 1 到 100 随机):

1 5 20 50 100

然后我想将这些数字放入这 5 个桶中:

a b c d e

使用一些散列函数来完成它。例如,也许像这样:

hash(1)   -> b
hash(5)   -> a
hash(20)  -> e
hash(50)  -> d
hash(100) -> c

想知道如何编写散列函数以使其接受一个数字 x来自数字的 D和一组数字 D(X)来自该域,并输出 1 个桶 b来自一组桶 B .

H : D(X) -> B

下次我可能会有 1 到 1,000 之间的 6 个数字,分为 6 个桶。那么我需要一个新的哈希函数,它使用这些约束(6 个数字,6 个桶,范围 1-1,000)。

目标是尽可能少的步骤。

注意:这个例子的哈希函数不会在大于 10,000 的域中取整数,而且整数集的大小也限制在一些小数字,比如 1,000。


更新

基本上我正在努力实现这一目标:

// var domain = [1, 2, ..., 100]
// var set = [1, 5, 20, 50, 100]
// var buckets = [1, 2, 3, 4, 5]

hash(1) // 2
hash(5) // 1
hash(20) // 5
hash(50) // 4
hash(100) // 3

function hash(integer) {
  if (integer == 1) return 2
  if (integer == 5) return 1
  if (integer == 20) return 5
  if (integer == 50) return 4
  if (integer == 100) return 3
}

但我不知道如何动态构造哈希函数。

一个解决方案(在 JavaScript 中)是像这样创建一个 map :

var map = {
  1: 2,
  5: 1,
  20: 5,
  50: 4,
  100: 3
}

但这有点作弊,因为 JavaScript 中的对象是作为下面的哈希表(或类似的东西)实现的。所以我正在寻找如何在低层次上做到这一点,基本上只是使用汇编给你的东西。

差不多,我想这样做:

           1                     
    5      |                     
    |      |                    20
    |      |             50     |
    |      |      100    |      |
[ slot1, slot2, slot3, slot4, slot5 ]

在哪里1以某种方式“散列”进入那个slot2在一个大小为 5 的数组中(对于这个示例,该插槽是任意的),等等。

最佳答案

假设您的整数值的域是从 0 到 n-1 的范围,并且您想要一组值 [x0, x1, .. ., xk-1] 映射到从 0 到 k-1 的值。

创建一个包含 n 个值的数组,其中包含大致相等数量的从 0 到 k-1 的数字,例如 [a0 = 0, a1 = 1, ..., ak = 0, ..., an = n%k].

然后对于初始集合中的每个 k 个值(xi,其中 i = 0 .. k-1),将此数组的第 k 个元素更改为 i,或者通过直接分配或通过与来自其他地方的值交换(注意不要破坏初始集合的前一个元素的值集)。

然后要对值 y 进行哈希处理,只需从该数组中获取第 y 个值即可。


演示

这是一个基本实现上述算法的 Javascript 演示,除了它不是用 0 到 k-1 的值预填充数组,它首先插入所选项目的哈希值,然后用从 0 到 k-1 的重复数字序列。通过使用随机序列而不是递增值,您可能会获得更好的抗碰撞性,但我希望您明白了。

var hash_array;

function generate_hash() {
  var i, j, k;
  var v = document.getElementById;
  var n = document.getElementById("n").value;
  // Create a new hash lookup table
  hash_array = Array(n);
  // Initialize every value to -1
  for (i=0; i<n; i++) hash_array[i] = -1;
  // Map the given values to the first k hash buckets
  var initial_values = document.getElementById("init").value.split(/ +/);
  k = initial_values.length;
  for (i=0; i<k; i++) {
    hash_array[initial_values[i]] = i;
  }
  // Fill the remaining buckets with values from 0 to k-1
  // This could be done by selecting values randomly, but
  // here we're just cycling through the values from 0 to k-1
  for (i=j=0; i<hash_array.length; i++) {
    if (hash_array[i] == -1) {
      hash_array[i] = j;
      j = (j + 1) % k;
    }
  }
  document.getElementById("gen").innerHTML = "Hash lookup table:<br>" + hash_array.join(", ");
}
<h2>Demo</h2>
<p>Creating a hash function that works on integer values  less than <i>n</i>. What is the value of <i>n</i>?<br>
<input type="number" id="n" min="6" max="100" value="20"/></p>
<p>Enter a few different values separated by spaces. These will hash to the first buckets<br/>
<input type="text" size="40" id="init" value="2 3 5 6 9"/></p>
<p id="gen"><button onclick="generate_hash(); return false">Generate hash table</button></p>

关于algorithm - 将域中的一组整数散列到一组桶中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51207863/

相关文章:

algorithm - 根据过去观察到的分组对最佳数据分组进行排名

algorithm - 循环法 - 动态权重

ruby - 将哈希值保存到 Ruby 上的文件

C(初学者): Why won't my qsort work? 编辑:从一个错误到另一个错误

string - 获取不带字符的字符串的所有子串的时间复杂度是多少?

ruby Hash 包括另一个哈希,深度检查

vector - 为什么对同一个向量进行两次哈希运算会得到不同的哈希码?

ruby-on-rails - 使用 zip 在 ruby​​ 中转置哈希

java - 如何在 Java 中使用 SHA384 生成 48 个字符的哈希

algorithm - 我们可以使用 Morris 遍历进行后序吗?