【问题标题】:Get index of element of an array java with hashCode使用 hashCode 获取数组 java 元素的索引
【发布时间】:2019-05-17 23:01:36
【问题描述】:

我有一个包含很多单词的字符串数组。我希望获取数组中包含的单词的索引(如果不包含则为-1)。

我首先创建了一个循环来搜索数组中的所有元素,同时增加一个变量,当我找到它时,我返回变量的值。

但是数组可能非常非常大,因此搜索所有元素非常慢。我决定在我的字符串数组中添加一个新单词之前,我会使用hashCode() % arrayLength 来获取我应该放置它的位置的索引。然后,为了恢复索引,我只需重用 hashCode() % arrayLength 即可立即知道它是什么索引。

问题是有时会出现“冲突”,两个元素在数组中可以有相同的索引。

有人知道如何处理它吗?或者任何其他替代方法可以更快地获取元素的索引?

【问题讨论】:

  • 您是否尝试重新实现HashMap
  • 而不是将对象放在数组中。为什么不将它们放在HashMap<Integer, Object> 中,其中键是哈希码。
  • @locus2k 不会处理哈希冲突的问题。
  • @DodgyCodeException 他没有遇到哈希冲突。他在另一个项目的数组中获得了相同的索引。他正在使用模运算来计算指数。即使使用不同的哈希值,使用模数也很容易得出相同的索引。

标签: java arrays hash hashcode


【解决方案1】:

您正在尝试使用数组实现Open Addressing。除非这是一个家庭作业,否则 Java 标准库已经有了解决搜索和冲突问题的类。

您可能想使用HashSet 来检查String 是否存在。在幕后它使用HashMap 实现Separate Chaining 来解决冲突。

String[] words = { "a" };
Set<String> set = new HashSet<>(Arrays.asList(words));
return set.contains("My Word") ? 1 : -1;

【讨论】:

    【解决方案2】:

    您所指的技术是哈希表的一般实现之一。它被称为线性探测,它是一种称为开放寻址的通用技术的形式。如果你根据hashCode() % array.length计算了单词的索引,发现有冲突(非空元素或者不是你要找的元素);那么你有三种方法来解决冲突:

    线性搜索

    这是通过增加位置并检查它是否为空或是否有您要查找的元素来完成的。也就是说,您的第二个位置将是(hashCode(input) + 2) % array.length,然后是(hashCode(input) + 3) % array.length,依此类推。这种方法的问题是,如果数组接近完全填充,您的插入或查找性能将降低到线性 O(n)。

    二次搜索

    这只是对上述技术的优化,如果您发现冲突,则通过二次跳跃。因此,您的第二个索引将是 (hashCode(input) + 2*2) % array.length,然后是 (hashCode(input) + 3*3) % array.length,依此类推,这有助于更快地到达正确的位置。

    双重哈希

    通过引入 另一个 散列函数 hashCode2() 与第一个函数结合使用,这甚至是一种更有效的解决方法。在这种情况下,您的下一个搜索索引将是 (hashCode(input) + 2*hashCode2(input)) % array.length,然后是 (hashCode(input) + 3*hashCode2(input)) % array.length,依此类推。

    你的跳跃分布越随机,它在大型哈希表中获得的性能就越好

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多