我有大量网址,我想实现自动完成功能。我不喜欢天真方法的复杂性,因为它与设定大小呈线性关系:
for(String url: urls) if(url.startsWith(input) {doSomething();}
现在我知道在Hash Set中,函数“contains()”在“O(1)”中起作用,但是没有“containsPrefix()”。有没有像Lucene这样的大型图书馆或者自己编写的简单方法?我没有问题这样做但是对于这样一个简单的问题来说似乎有点过头了所以我想知道是否有一个现有的简单解决方案: - )
从我的计算机科学课程中,我记得一个由字符串片段组成的树,但我忘了它是如何调用的。它的工作原理如下:
[car, care, carrot,carrotville]->
car
|
-/
-e
-rrot
|
----ville
P.S。:如何调用返回字符串为前缀的所有字符串的方法?就像a是b的前缀,b是什么?
答案 0 :(得分:2)
如果您需要有效地找到字符串的前缀,请使用Trie,这是为此目的精确设计的数据结构:
trie或前缀树是一种有序树数据结构,用于存储关键数组,其中键通常是字符串。与二叉搜索树不同,树中没有节点存储与该节点关联的密钥;相反,它在树中的位置定义了与之关联的键。节点的所有后代都具有与该节点关联的字符串的公共前缀,并且根与空字符串相关联
与sample implementations的两个链接。
答案 1 :(得分:1)
很久以前我在这里放了一个简单的Trie实现:
http://code.google.com/p/triebag/source/browse/trunk/src/triebag/tries/SimpleTrie.java
然而,这不是一个紧凑的Trie,因此每个字符创建一个节点,创建一个紧凑的节点有点棘手。
答案 2 :(得分:1)
一个很好的替代算法是ternary search tree(内存效率更高)https://github.com/varunpant/TernaryTree/tree/master/TernaryTree
这是java http://algs4.cs.princeton.edu/52trie/TrieST.java.html
中的trie答案 3 :(得分:0)
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();
注意:为简单起见,前缀字符串不会被转义。正则表达式字符[,],\,*,?,$,^,(,),{,}和|必须以\。
为前缀