【发布时间】:2015-12-09 22:29:07
【问题描述】:
作为我编程课程的一部分,我得到了一个练习来实现我自己的字符串集合。我计划使用 ArrayList 集合或类似的集合,但其中一个限制是我们不允许使用任何 Java API 来实现它,因此只允许使用数组。我本可以使用数组来实现这一点,但是效率以及测试此代码的数据量非常重要。有人建议我使用哈希表或有序树,因为它们比数组更有效。在做了一些研究之后,我决定使用哈希表,因为它们看起来很容易理解和实现,但是一旦我开始编写代码,我意识到它并不像我想象的那么简单。
以下是我提出的问题,并希望得到一些建议,了解什么是再次解决这些问题的最佳方法,同时考虑到效率:
- 实际大小:如果我理解正确,哈希表没有排序(索引),这意味着项目之间会有间隙,因为哈希函数给出了不同的索引。那么我如何知道数组何时已满,我需要调整它的大小?
- 调整大小:我需要使用数组创建动态数据结构的困难之一。因此,如果我有一个数组 String[100],一旦它变满,我将需要调整它的大小,我决定每次将其增加 100,所以一旦我这样做,我需要更改所有现有值的位置,因为它们哈希键在计算时会有所不同:
int position = "orange".hashCode() % currentArraySize;
因此,如果我尝试找到某个值,它的哈希键将与数组较小时的不同。
- HASH FUNCTION:我还想知道 String 类中的内置
hashCode()方法是否高效且适合我要实现的功能,或者创建自己的方法是否更好。 - 处理多次出现:要求之一是能够添加多个相同的单词,因为我需要能够计算该单词在我的集合中存储的次数。由于它们将具有相同的哈希码,因此我计划在下一个索引处添加下一个匹配项,希望会有一个间隙。我不知道这是否是最好的解决方案,但这里我是如何实现它的:
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;
}
提前感谢您的建议。请问有什么需要澄清的。
附:字长不固定,变化很大。
更新感谢您的建议,我知道我确实犯了一些愚蠢的错误,我会努力做得更好。所以我采纳了你的所有建议并迅速提出了以下结构,它并不优雅,但我希望它是你大致的意思。我确实不得不做出一些判断,例如桶大小,现在我将元素的大小减半,但是有没有办法计算或一些通用值?另一个不确定因素是通过什么因素来增加我的数组,我应该乘以某个 n 数还是添加固定数也适用?另外我想知道一般效率,因为我实际上是在创建类的实例,但是 String 是一个类,所以我猜性能差异应该不会太大?
【问题讨论】:
-
你看wikipedia page about hash tables了吗?它描述了调整大小和寻址的多种策略。