Java:在大型字典中搜索字符串的非常快速的方法

Java:在大型字典中搜索字符串的非常快速的方法,java,string,performance,dictionary,lookup,Java,String,Performance,Dictionary,Lookup,我有一本包含120万个字符串的大字典。作为输入,我将得到一个句子,我需要检查输入句子中的每个单词是否存在于词典中 对我来说,性能是最重要的,因此我想把这本字典保存在内存中。我想在不到一毫秒的时间内完成字典查找。请建议我如何才能做到这一点?任何现有的外部API都可以这样做吗?如果您愿意使用外部API,我建议您选择。性能是最重要的,这完全符合您的要求 可以找到JavaAPI 您可以为所有关键字编制索引,然后为其提供一个文档(在您的案例中为句子) 索引: for(String obj:keywordL

我有一本包含120万个字符串的大字典。作为输入,我将得到一个句子,我需要检查输入句子中的每个单词是否存在于词典中


对我来说,性能是最重要的,因此我想把这本字典保存在内存中。我想在不到一毫秒的时间内完成字典查找。请建议我如何才能做到这一点?任何现有的外部API都可以这样做吗?

如果您愿意使用外部API,我建议您选择。性能是最重要的,这完全符合您的要求

可以找到JavaAPI

您可以为所有关键字编制索引,然后为其提供一个文档(在您的案例中为句子)

索引:

for(String obj:keywordLst){
    client.prepareIndex("myindex", ".percolator", obj)
            .setSource(XContentFactory.jsonBuilder()
                .startObject()
                    .field("query", QueryBuilders.matchPhraseQuery("content", obj)) 
                .endObject())
            .setRefresh(true) 
    .execute().actionGet();
}
XContentBuilder docBuilder = XContentFactory.jsonBuilder().startObject();
docBuilder.field("doc").startObject(); 
docBuilder.field("content", text);
docBuilder.endObject(); //End of the doc field
docBuilder.endObject(); //End of the JSON root object

PercolateResponse response = client.preparePercolate().setSource(docBuilder)
            .setIndices("myindex").setDocumentType("type")
            .execute().actionGet();


for(PercolateResponse.Match match : response) {
    //found matches
}
搜索:

for(String obj:keywordLst){
    client.prepareIndex("myindex", ".percolator", obj)
            .setSource(XContentFactory.jsonBuilder()
                .startObject()
                    .field("query", QueryBuilders.matchPhraseQuery("content", obj)) 
                .endObject())
            .setRefresh(true) 
    .execute().actionGet();
}
XContentBuilder docBuilder = XContentFactory.jsonBuilder().startObject();
docBuilder.field("doc").startObject(); 
docBuilder.field("content", text);
docBuilder.endObject(); //End of the doc field
docBuilder.endObject(); //End of the JSON root object

PercolateResponse response = client.preparePercolate().setSource(docBuilder)
            .setIndices("myindex").setDocumentType("type")
            .execute().actionGet();


for(PercolateResponse.Match match : response) {
    //found matches
}

因此,您只需要从字典中获取一组单词,然后查看它是否包含该句子的单词集

Set<String> dictionaryIndex = new HashSet<>();
Set<String> sentence = new HashSet<>();

if (!dictionaryIndex.containsAll(sentence)) {
    ...

你甚至可以考虑拼写库。他们保留较小的字典,并使用词干:“learn”来表示学习、学习、学习。

我认为120万个字符串将无法放入内存,或者很容易超出内存的大小限制(考虑一个糟糕的情况,平均字符串长度为256)

如果允许进行某种预处理,我认为您最好先将字符串序列减少为单词序列。这意味着您首先将数据转换为另一组数据,这些数据将很容易放入内存中,并且不会溢出


之后,我认为您可以依赖于内存中的数据结构,比如HashMap

你试过只使用HashMap吗?@immibis:HashMap可能不好,如果你需要前缀搜索、查找复数单词等。我建议你使用Range
HashMap
。i、 e,在一张地图中保留a-d中的单词,在另一张地图中保留e-g中的单词,等等。。并使用多个线程查找句子中的不同单词。最后,结合每个线程的结果(使用executor for threading…)我一定会推荐您使用hashmap。。但是有了优化。。你能给我推荐一些把字符串压缩成单词序列的技巧吗?在我的例子中,字典是城市的名称。我的意思是,由于你的工作是检查输入句子中的每个单词是否在120万个字符串中,我认为你最好将120万个字符串拆分成另一个“字典”。只需对所有字符串进行预处理,将其拆分为单词,保存到字典中即可。在哪种方法中,字典可以是Map或Set,随便什么。然后,使用字典,只需查找字典,就可以发现给定句子中的单词在120万个字符串的列表中。