仅使用数组实现高效的数据结构

时间:2015-12-09 22:29:08

标签: java arrays hash

作为编程课程的一部分,我接受了练习来实现自己的String集合。我计划使用ArrayList集合或类似的,但其中一个约束是我们不允许使用任何Java API来实现它,因此只允许使用数组。我可以使用数组实现这一点,但效率非常重要,以及将使用此代码测试的数据量。我被建议使用哈希表或有序的tress,因为它们比数组更有效。在做了一些研究之后,我决定使用哈希表,因为它们似乎很容易理解和实现,但是一旦我开始编写代码,我意识到它并不像我想象的那样直截了当。

以下是我提出的问题,并希望就什么是以效率为目标再次解决这些问题的最佳方法提出一些建议:

  1. 实际大小:如果我理解正确哈希表没有排序(索引),这意味着项之间会有间隙,因为哈希函数给出不同的索引。那么我如何知道数组何时已满并且我需要调整它的大小呢?
  2. RESIZE:使用数组创建动态数据结构所需的困难之一。所以,如果我有一个数组String [100],一旦它变满,我将需要通过一些因素调整它,我决定每次增加100,所以一旦我这样做,我需要改变所有现有值的位置,因为他们的计算密钥时,散列密钥会有所不同:
  3. int position = "orange".hashCode() % currentArraySize;
    

    因此,如果我尝试找到某个值,则其哈希键将与数组较小时的哈希键不同。

    1. HASH FUNCTION:我也想知道String类中的内置hashCode()方法是否有效且适合我想要实现的内容,或者创建自己的方法更好。
    2. 处理多个事件:其中一个要求是能够添加多个相同的单词,因为我需要能够计算单词在我的集合中存储的次数。由于它们将具有相同的哈希码,因此我计划在下一个索引处添加下一个匹配项,希望存在间隙。我不知道这是否是最好的解决方案,但在此我是如何实施的:
    3. public int count(String word) {
          int count = 0;
          while (collection[(word.hashCode() % size) + count] != null && collection[(word.hashCode() % size) + count].equals(word))
              count++;
          return count;
      }
      

      提前感谢您的建议。请询问任何需要澄清的事情。

      P.S。单词的长度不固定,变化很大。

      更新感谢您的建议,我知道我确实做过一些愚蠢的错误,我会更好地尝试。所以我接受了你所有的建议,并迅速提出了以下结构,它不优雅,但我希望它是你粗略的意思。我确实做了很少的判断,例如铲斗尺寸,现在我将元素的大小减半,但有没有办法计算或一些一般值?另一个不确定因素是通过什么因素来增加我的数组,我应该乘以一些n数或添加固定数也适用?我也想知道一般的效率,因为我实际上是在创建类的实例,但是String是一个类,所以我猜测性能上的差异不应该太大?

2 个答案:

答案 0 :(得分:1)

实际大小:当元素总数超过桶数乘以一个称为加载因子的数字(默认为0.75)时,内置Java HashMap会调整大小。 确实考虑了实际已满的桶数。你没必要。

调整大小:是的,在调整表格大小时你必须重新整理所有内容,其中包括重新计算其哈希值。

  

因此,如果我试图找到某个值,它的散列键将与数组较小时的散列键不同。

烨。

哈希功能:是的,你应该使用内置的hashCode()功能。这对于基本目的来说已经足够了。

处理多种情况:这很复杂。一个简单的解决方案就是让给定字符串的哈希条目也保持计数该字符串出现的次数。也就是说,不要在哈希表中保留相同字符串的多个副本,而是保持int以及每个String计算其出现次数。

答案 1 :(得分:1)

  

那么我怎么知道数组何时已满并且我需要调整它的大小呢?

您可以跟踪HashMap的大小。当size used> capacity * load factor您可以整体或部分地增加基础数组。

  

int position =" orange" .hashCode()%currentArraySize;

需要考虑的一些事项。

  • 负值的%为负值。
  • Math.abs可以返回负值。
  • 使用带有位掩码的&会更快,但是你需要的是2的幂。
  

我还想知道String类中的内置hashCode()方法是否有效且适合我想要实现的内容,或者更好地创建自己的方法。

内置的hashCode被缓存,因此速度很快。然而,它不是一个很好的hashCode,并且较低位的随机性较差,短字符串的位较高。您可能希望实现自己的哈希策略,可能是64位的。

  

处理多项事件:

通常使用每个键的计数器来完成。这样你可以说32767重复(如果你使用short)或20亿(如果你使用int)重复相同的键/元素。