如何在Java中创建简单的前缀索引?

如何在Java中创建简单的前缀索引?,java,indexing,prefix,Java,Indexing,Prefix,我有一大组URL,我想实现一个自动完成。我不喜欢天真方法的复杂性,因为它与设置的大小成线性关系: for(String url: urls) if(url.startsWith(input) {doSomething();} 现在我知道在散列集中,函数“contains()”在“O(1)”中工作,但没有“containsPrefix()”。有没有一种简单的方法不用像Lucene这样的大型库,也不用自己编写代码?我这样做没有问题,但对于这样一个简单的问题来说,这似乎有些过头了,所以我想知道是否存

我有一大组URL,我想实现一个自动完成。我不喜欢天真方法的复杂性,因为它与设置的大小成线性关系:

for(String url: urls) if(url.startsWith(input) {doSomething();}
现在我知道在散列集中,函数“contains()”在“O(1)”中工作,但没有“containsPrefix()”。有没有一种简单的方法不用像Lucene这样的大型库,也不用自己编写代码?我这样做没有问题,但对于这样一个简单的问题来说,这似乎有些过头了,所以我想知道是否存在一个现有的简单解决方案:-)

在我的计算机科学课上,我记得有一棵由字符串片段组成的树,但我忘了它是如何命名的。它是这样工作的:

[car, care, carrot,carrotville]->

car
|
-/
-e
-rrot
  |
  ----ville

注意:如何调用返回字符串前缀的所有字符串的方法?例如,如果a是b的前缀,那么b对a是什么?

如果需要高效地查找字符串的前缀,请使用a,这是一种专门为此目的设计的数据结构:

trie或前缀树是一种有序树数据结构,用于存储键通常为字符串的关联数组。与二叉搜索树不同,树中没有节点存储与该节点关联的密钥;相反,它在树中的位置定义了与之关联的键。节点的所有子体都有一个与该节点关联的字符串的公共前缀,根与空字符串关联


与的两个链接。

很久以前,我在这里放置了一个简单的Trie实现:


但是,这不是一个紧凑的Trie,因此它会为每个字符创建一个节点,创建一个紧凑的节点有点棘手。

一个很好的替代算法是a(内存效率更高)


下面是java中的一个trie,Regexp实现java.util.regex.Pattern可以有效地处理前缀:

StringBuilder buffer = new StringBuilder();
for (String prefix : prefixes) {
    if (buffer.length() > 0)
        buffer.append("|");
    buffer.append(prefix);
}
Pattern prefixPattern = Pattern.compile("^(" + buffer + ")");
boolean containsPrefix = prefixPattern.matcher(stringToTest).find();
您可以测试所有前缀:

StringBuilder buffer = new StringBuilder();
for (String prefix : prefixes) {
    if (buffer.length() > 0)
        buffer.append("|");
    buffer.append(prefix);
}
Pattern prefixPattern = Pattern.compile("^(" + buffer + ")");
boolean containsPrefix = prefixPattern.matcher(stringToTest).find();

注意:为简单起见,前缀字符串不会转义。Regexp字符[,],\,*,?,$,^,(,),{,}和|的前缀必须是\。

您想做什么?自动在每个字符串的开头添加一些文本?我想知道我的字符串是哪个字符串的前缀,这样我就可以给它们作为自动完成建议。这太棒了!我不介意每个字符有一个节点,但我会保留这个问题,以防有人有一个节点有多个。Np,compact版本使用的节点减少了大约50%(至少对于字典中的土耳其语单词而言)。这是测试代码,所以您可以看到它的实际应用,我希望没有bug:)我试过你的SimpleTrie,但它似乎对我不起作用。首先,构造函数不是公共的,在我更改了它之后,以下测试没有返回任何内容:
SimpleTrie trie=newsimpletrie();三.添加(“x”、“x”);三、添加(“xy”、“xy”);迭代器it=trie.getItemsWithPrefix(“x”);while(it.hasNext())System.out.println(it.next())完美!我用了一个从和它的工作在第一次尝试!