我有一个包含很多单词的String数组。我希望获取数组中包含的单词的索引(如果不包含则为-1)。
我首先做了一个循环,在递增变量的同时搜索数组中的所有元素,当我找到它时,我就返回了变量的值。
但是,数组可能非常非常大,因此搜索所有元素非常慢。我已经决定,在向字符串数组中添加新单词之前,我将使用hashCode() % arrayLength
来获取应该放置它的位置的索引。然后,为了找回索引,我只需要重用hashCode() % arrayLength
就可以立即知道它是什么索引。
问题在于,有时存在“冲突”,并且两个元素在数组中可以具有相同的索引。
任何人都知道如何处理吗?还是有其他替代方法可以更快地获取元素的索引?
答案 0 :(得分:2)
您正在尝试使用数组实现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;
答案 1 :(得分:0)
您所指的技术通常是哈希表的一种实现。它称为线性探测,它是一种称为“开放寻址”的通用技术的一种形式。如果您已经基于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
,依此类推。
您的跳转越随机分布,通过大型哈希表获得的性能就越好
希望这会有所帮助。