【问题标题】:Finding n keys that all hash to same hash value找到所有散列到相同散列值的 n 个键
【发布时间】:2018-07-27 11:16:16
【问题描述】:

给出的哈希函数:

public int hash4(int k) {
    Random rand = new Random(k);
    return rand.nextInt(size);
}

目标是找到 n(size) 个 key(k) 使用这个散列函数散列到相同的散列值(导致冲突)。大小是用户传入的常量,大小永远不会大于 1000。一个键的最大值是 n^2,你不能一遍又一遍地使用同一个键。任何帮助将不胜感激!

我解决这个问题的尝试是使用数字 1-n 作为键从 1 循环到 n,寻找模式。

【问题讨论】:

  • 什么是size?您是在尝试暴力破解,还是利用有关 Random 工作原理的知识?
  • 这听起来像是一个家庭作业问题。到目前为止,您尝试过什么?
  • Size 是用户传入的常量,我将其添加到问题中。
  • 你可以在网上找到 Random 的确切工作原理,所以我认为我应该使用这些信息来弄清楚。即使有了这些信息,我也看不到任何模式会导致在给定特定大小时所有键都给出相同的哈希值
  • 您似乎使用n 作为您想要找到哪个哈希值相同的键的数量。如果是这样,“如果 n 是 2 的幂,那么所有键都哈希到相同的值”是什么意思?寻找 4 个(而不是 3 个)键的问题如何神奇地导致所有键散列到相同的值?你的措辞令人困惑。无论如何,如果您需要家庭作业方面的帮助,您应该描述您的努力。

标签: java random hash collision


【解决方案1】:

假设有 n 个桶,有 n2 个键,使用pigeonhole principle,我们知道一个桶至少有 n 个键

要解决这个问题,我们需要遍历所有键

int keys = n * n;
for(int i = 0; i < keys; i++)

接下来我们查看哪些键发生冲突的方法是将每个键存储在一个列表/集合中,用于每组冲突

List<List<Integer>> collisions = new ArrayList<List<Integer>>(n);
for(int i = 0; i < n; i++)
    collisions.add(new LinkedList<Integer>());
collisions.get(hash(key)).add(key);

一旦我们有了所有的碰撞,就很容易找到一个至少有 n 次碰撞的列表

for(List<Integer> collision : collisions)
    if(collision.size() >= n)
        return collision; //or just print

把它们放在一起......

List<Integer> findCollisions(int n)
{
    List<List<Integer>> collisions = new ArrayList<List<Integer>>(n);
    for(int i = 0; i < n; i++)
        collisions.add(new LinkedList<Integer>());
    int keys = n * n;

    for(int i = 0; i < keys; i++)
        collisions.get(hash(i)).add(i);

    for(List<Integer> collision : collisions)
        if(collision.size() >= n)
            return collision;
    return null; //this should never happen, due to pigeonholes, but compiler doesn't know
}

【讨论】:

  • 太棒了!我还没有完全掌握这个概念,但是由于这个答案,我现在有点理解了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多