0

我有一个直方图,它是一个向量/数字列表。获得这种直方图的哈希码的简单有效算法是什么?哈希码只需要在哈希值上分割图像而不是比较图像。

此应用程序不关心安全性,因此加密功能不必要地缓慢。

4

2 回答 2

0

我可能没有正确理解您的问题,但是哈希图已经在 matlab 中,它们只是名称不同

容器.maps

于 2015-03-24T23:06:20.687 回答
0

散列列表的方法是将每个项目的散列组合起来。Java为列表实现哈希函数,如下所示:

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

显着特性:

  1. 每个空列表的哈希码都是1.
  2. 具有不同数量元素的列表的哈希码很可能是不同的。
  3. 具有相同数量元素的列表的哈希码更有可能发生冲突。具有不同顺序的相同元素的列表会发生冲突;列表的哈希码[1,2][2,1]不幸的是相同的。
  4. 这是一个很大的缺点,但并不像你一开始想象的那么大。哈希表实现了一个回退,它首先检查哈希码是否相等,然后是完全相等。如果排序的差异出现在列表的前面附近,则此后备检查很快。在最坏的情况下,它只需要与列表长度相等的比较次数。

总而言之,对于您的用例来说,这将是一个非常好的哈希函数,即使您使用每个直方图条目的数值作为其哈希码。哈希函数真正要避免的问题是公分性,这意味着您希望哈希函数的输出落入哈希表的不同存储桶中。如果您想了解更多信息,维基百科文章涵盖了良好哈希函数的属性。

要为数字列表获得更好的哈希码,我们应该查看单个数字的更好哈希码,特别是这个答案

unsigned int hash(unsigned int[] list) {
    unsigned int hashCode = 0;
    for (int i = 1; i < list.length; i++) {
        hashCode = hashCode + list[i];
        hashCode = ((hashCode >> 16) ^ hashCode) * 0x45d9f3b;
        hashCode = ((hashCode >> 16) ^ hashCode) * 0x45d9f3b;
        hashCode = ((hashCode >> 16) ^ hashCode);
    }
    return hashCode;
}

认为这是一个很好的改编,但我不是一个期望。

关于溢出的效率,除非你必须为它处理异常,否则它并不是一个主要的减速。在 Java 中,算术永远不会抛出溢出异常,而只是将其包装到最小值或最大值。只要您的哈希表实现支持它,使用负哈希码并没有真正的缺点。

于 2015-03-24T22:53:37.220 回答