【问题标题】:How to use result from a hash function to get an array index?如何使用哈希函数的结果来获取数组索引?
【发布时间】:2016-03-02 06:46:27
【问题描述】:

我正在学习布隆过滤器,并且正在研究 JavaScript 中的各种哈希函数。

例如,我在另一个 Stack Overflow 答案中找到了这个:

在这里找到https://stackoverflow.com/a/7616484/5217568)

String.prototype.hashCode = function() {
  var hash = 0, i, chr, len;
  if (this.length == 0) return hash;
  for (i = 0, len = this.length; i < len; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};

如果我跑:

String.prototype.call(null, "hello") 

我得到的数值是:99162322 (另外两个散列函数得到了我:1335831723 和 120092131)。

现在,如果我创建一个具有 3 个哈希函数和 18 个索引(k=3,m=18)的假设布隆过滤器,这些大值如何在索引为 0-17 的数组中编入索引?

【问题讨论】:

  • 我认为应该使用哈希函数来确定存储数据的索引

标签: javascript data-structures hash hashtable bloom-filter


【解决方案1】:

使用the remainder/modulo operator % 将随机生成的值包装在特定范围内。

如果您有 18 个元素(索引 0 到 17),您可以获得带有 99162322 % 18 (16) 的索引。

如果哈希值的个数不是索引个数的倍数,结果就会有偏差。例如,如果您的哈希值是从 0 到 4 的五个值之一,但您将其映射到从 0 到 2 的三个索引,它将偏向于 0(0 % 33 % 3)和 1( 1 % 34 % 3) 超过 2 个(仅限 2 % 3)。根据您的需要,如果哈希值的数量远远大于索引的数量,则偏差可能是可以接受的。如果你想避免它,你需要一个方案来生成一个新的散列输入,如果散列结果来自偏差诱导范围。像这样的:

function hashIndex(string, length, hashValueCount) {
  var minBiasedIndex = hashValueCount - (hashValueCount % length);
  for (var i = 0; ; i++) {
    var hashInput = string + ":" + String(i);
    var hashResult = hash(hashInput);
    if (hashResult < minBiasedIndex) {
      return hashResult % length;
    }
  }
}

【讨论】:

  • 这很有趣,谢谢。你能帮助澄清你的函数中的参数吗?对于我在问题中的示例,它会是 hashIndex("hello", 18, 17) 吗?其中18是数组的长度,17是数组中的最高索引?
  • 我认为可能的哈希值的数量 (hashValueCount) 对你来说应该是 2 的 31 次方。我认为您的哈希函数可以返回任何无符号的 31 位整数,尽管我可能会误解。我认为由于 % -- oops 的限制,我的 minBiasedIndex 计算可能太大而无法工作。 (另外,我最初的函数中有一些错误。我认为它现在已经修复了。)
  • (是的,长度为 18,字符串为“hello”。)鉴于您可能的哈希值数量远大于索引数量,我 认为 i> 偏差非常小——小于 0.000001%。我可能会考虑直接使用模运算符并接受这种偏差,具体取决于应用程序。
猜你喜欢
  • 2018-08-29
  • 2013-07-06
  • 2013-01-02
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2012-10-12
相关资源
最近更新 更多