快速字符串搜索,如startsWith()不等于()

时间:2010-07-28 16:05:53

标签: java string search performance

我有一个有序列表(字典 - 100K字)和许多单词经常在这个列表中搜索。因此,性能是一个问题。我知道HashSet.contains(theWord)或Collections.binarySearch(sortedList,theWord)非常快。但实际上我并不是在寻找整个单词。

我想要的是让我们说搜索“se”并让所有单词以“se”开头。那么Java或任何库中是否有现成的解决方案?

更好的示例:在排序列表中,以下操作的快速解决方案

List.subList(String beginIndex,String endIndex)//返回间隔

myWordList.subList(“ab”,“bc”);

注意:这是一个非常相似的问题,但接受的答案并不令人满意。 Overriding HashSet's Contains Method

4 个答案:

答案 0 :(得分:9)

您在这里寻找的是一个名为'trie'的数据结构:

http://en.wikipedia.org/wiki/Trie

它将字符串存储在由prefix编制索引的树中,其中树的第一级包含字符串的第一个字符,第二级包含第二个字符,等等。结果是它允许您提取非常大的子集前缀极快的字符串组。

答案 1 :(得分:2)

Trie结构非常适合字典和查找具有公共前缀的单词。 Google Collections / Guava中有Trie implementation的贡献。

答案 2 :(得分:2)

对新结构的需求确实很大:问题可以通过列表中的二进制搜索来解决。特别是,您可以修改二进制搜索以返回第一个匹配元素(具有指定前缀的第一个元素)。

List.subList(String beginIndex,String endIndex)//返回间隔
我可能是傻瓜,但是什么样的索引有字符串类型?你能澄清一下吗?

答案 3 :(得分:1)

您的搜索结果将是您订购的单词列表中的范围。为此,您需要该范围的第一个和最后一个元素的索引。

要获得第一个,请使用原始搜索字符串(“se”)运行二进制搜索,并将其与每次迭代中的当前位置进行比较。当当前位置的单词大于搜索字符串时停止,但当前第1个单词较低。

要获取最后一个索引,请在搜索项+“z”(“sez”)上运行另一个二进制搜索,但现在仅在当前索引处的单词小于“sez”但当前+ 1更大时停止。

最后通过编程语言中可用的任何方式返回由第一个和最后一个索引标记的范围。

此方法基于两个假设:

  • 字符串比较看到“b”大于“az”
  • “z”是单词列表中最高的char值

我在JavaScript数据操作库(jOrder.net)中实现了这个算法。

相关问题