Java-搜索提供前几个字符的字符串集合
我有一个字符串集合,我只想搜索前几个字符 例如,考虑字符串的列表:[汤姆,托马兹,爱丽丝,托尔斯泰,约翰]。字符串[to]将导致列表[tom、tomaz、tolstoy] 性能是这里的一个主要问题,列表可能非常大 优化这一点的最佳方法是什么?索引?分类?怎么做Java-搜索提供前几个字符的字符串集合,java,search,collections,Java,Search,Collections,我有一个字符串集合,我只想搜索前几个字符 例如,考虑字符串的列表:[汤姆,托马兹,爱丽丝,托尔斯泰,约翰]。字符串[to]将导致列表[tom、tomaz、tolstoy] 性能是这里的一个主要问题,列表可能非常大 优化这一点的最佳方法是什么?索引?分类?怎么做 谢谢 看看索尔和卢森。他们通过索引进行字符串搜索,或者您也可以按照其他人的建议编写自己的 如果像这样搜索是一个优先事项,并且不会与您的其他要求发生冲突,我建议您查看以整理数据。如果您坚持使用列表,您的选择是有限的。它根本不适合做这种事情
谢谢 看看索尔和卢森。他们通过索引进行字符串搜索,或者您也可以按照其他人的建议编写自己的
如果像这样搜索是一个优先事项,并且不会与您的其他要求发生冲突,我建议您查看以整理数据。如果您坚持使用列表,您的选择是有限的。它根本不适合做这种事情 执行您正试图执行的操作的数据结构称为Trie 一个快速的google从杜克大学推出了这个java实现:
假设您的列表足够小,可以保存在内存中,我会使用一个
这将为您提供一个与前缀长度成比例的查找时间。如果您想完全在内存中执行此操作,而不需要任何依赖项,这里有一个快速选项:
static int MAX_PREFIX = 3;
Map<String, List<String>> map = new HashMap<String, List<String>>();
public void addItem(String item) {
for (int i = 0; i < MAX_PREFIX && i < item.length(); i++) {
String prefix = item.substring(0, i);
List<String> matches = map.get(prefix);
if (matches == null) {
matches = new ArrayList<String>();
map.put(prefix, matches);
}
matches.add(item);
}
}
public List<String> getMatches(String prefix) {
List<String> matches = map.get(prefix);
return matches == null ? Collections.<String>emptyList() : matches;
}
static int MAX_PREFIX=3;
Map Map=newhashmap();
公共无效附加项(字符串项){
对于(int i=0;i
这将非常快,因为它只是一个
映射
查找,从前缀字符串
直接转到所需结果的列表。如果你的列表太大,以至于它不适合内存,那么你需要考虑外部的。如前所述,您可能希望查看Lucene以获取本地索引。或者数据库,只需索引列并执行类似“prefix%”的查询。trie是通用的解决方案,正如已经建议的那样,但是如果您想要一个轻量级且相对快速的解决方案,而不需要外部依赖项,只需将所有字符串放入树集
并使用tailSet()
查找与前缀匹配的第一个元素,然后遍历尾集,直到找到不匹配的字符串。(注意:如果没有字符串与前缀匹配,那么这甚至可能是第一个元素。)
如果您的列表不超过几千个字符串,那么这种方法在实践中已经足够好了。是否可以使用数据库?有些索引针对此类搜索进行了优化如果可以,也许可以使用trie而不是集合,因为它更适合此类搜索。尝试和字典自动机最适合此任务。您能告诉我们非常大是什么意思吗?给我们一个大概的数量级。您希望字符串集合经常更改还是基本固定?在Trie上的内存需求和插入时间是惊人的。也就是说,随机访问时间变为O(1),如果你不在乎这些,只想要最快的访问时间,这是很好的。我在某种程度上假设列表是提前知道的,所以我对读取访问和简单性进行了优化。插入时间在这里并不可怕,你可以插入大约百万/秒,最大前缀为3(我只是试了一下)。max prefix越长,但越差。时间是相对的:)这里的单个插入是prefix\u len哈希查找和插入,而在Trie中,它是遍历prefix\u len节点后的单个插入。这也会为每个项消耗内存中的(前缀\u len*size\u of \u ref)+项大小(最小值,忽略哈希表本身和键冲突)。尽管如此,访问时间接近O(1),其中Trie最坏的情况是O(n)。我并不反对Trie的优点:)只是提供了一个可能适合该用例的替代方案。