如何处理相同的哈希与相同的密钥?

时间:2017-07-04 06:42:37

标签: hash logic

这个问题不是特定于任何编程语言,我对通用逻辑更感兴趣。

通常,关联映射会获取一个键并将其映射到一个值。据我所知,实现要求密钥是唯一的,否则值会被覆盖。好的。

因此,让我们假设上面是通过一些哈希实现来完成的。 如果两个不同的键获得相同的哈希值怎么办?我正在以底层数组的形式考虑这一点,其索引是所述键上的散列结果。有可能多个唯一键被映射到相同的值是吗?如果是这样,这样的实现如何处理这个? 如何处理相同哈希与处理相同密钥不同?由于相同的密钥会导致覆盖,相同的哈希会保留该值。
我理解哈希碰撞,所以我知道链接和探测。实现是否会迭代散列到特定索引的当前值并确定密钥是否相同? 当我在寻找答案时,我发现了这些链接:
1. What happens when a duplicate key is put into a HashMap?
2. HashMap with multiple values under the same key
然而,他们没有回答我的问题。我们如何区分相同的哈希与相同的密钥?

2 个答案:

答案 0 :(得分:3)

通过比较键。如果你看一下哈希映射的面向对象实现,你会发现它们通常需要在密钥类型上实现两种方法:

bool equal(Key key1, Key key2);
int hash(Key key);

如果只能给出散列函数并且没有相等的函数,则限制散列映射基于语言的默认相等性。这并不总是令人满意的,因为有时需要将键与不同的相等函数进行比较。例如,如果键是字符串,则应用程序可能需要进行不区分大小写的比较,然后它将传递散列函数,该散列函数在散列之前转换为小写,以及忽略大小写的相等函数。

哈希映射将密钥与每个对应值一起存储。 (通常,这是指向最初存储的密钥对象的指针。)对哈希映射的任何查找都必须在找到匹配的哈希后进行密钥比较,以验证密钥是否实际匹配。

例如,对于在每个存储桶中存储列表的非常简单的哈希映射,列表将是(键,值)对的列表,并且任何查找都会比较每个列表条目的键,直到找到匹配为止。在伪代码中:

Array<List<Pair<Key, Value>>> buckets;
Value lookup(Key k_sought) {
    int h = hash(k_sought);
    List<Pair<Key, Value>> bucket = buckets[h];
    for (kv in bucket) {
        Key k_found = kv.0;
        Value v_found = kv.1;
        if (equal(k_sought, k_found)) {
            return v_found;
        }
    }
    throw Not_found;
}

答案 1 :(得分:2)

您无法判断索引中的键是什么,因此您无法迭代这些值以查找有关键的任何信息。您将要么必须保证0次冲突,要么存储经过哈希处理的信息以提供索引。

如果您的结构中只存储了值,则无法判断它们是否具有相同的键或仅具有相同的哈希值。您需要存储密钥以及要知道的值。

相关问题