Java 从已排序的单词列表中高效地获取文档的前k个单词

Java 从已排序的单词列表中高效地获取文档的前k个单词,java,algorithm,sorting,Java,Algorithm,Sorting,我有一个单词列表,以文档语料库的频率升序排列 从每个文档中,我只想从排名列表中提取前k个单词,即根据所有计数,我想要文档中最不常用的k个单词 在java中实现这一点最有效的方法是什么 一个简单的实现是: public List<String> getTopK(List<String> wordCounts, Set<String> document, int k) {//wordcounts are in ascending order

我有一个单词列表,以文档语料库的频率升序排列

从每个文档中,我只想从排名列表中提取前k个单词,即根据所有计数,我想要文档中最不常用的k个单词

在java中实现这一点最有效的方法是什么

一个简单的实现是:

public List<String> getTopK(List<String> wordCounts, Set<String> document, int k) {//wordcounts are in ascending order        
    List<String> topK = new ArrayList<>(); //the list to be returned
    for (String topWord : wordCounts) { //given in ascending order of frequency
        if (document.contains(topWord)) { //assume HashSet --> O(1) for contains
            topK.add(topWord);  //again O(1) for add
            k--;
        }
        if (k == 0) {
            break;
        }
    }
    return topK;
}

我必须对D文档中的每一个文档以及最坏情况下的每一个W字的每一个字都这样做,因此,总的OD*W复杂度太高了,D和W的复杂度都在数百万左右。

而不是将单词的df存储在一个排序列表中,使用map word->df,然后对每个文档遍历所有单词并取最前面的k。使用这种方法,复杂度将是OD*w,其中w是一个文档中的字数,比w是所有文档中的字数少得多


因为OD*w是语料库中单词的大小,你做得再好不过了。

你对每个单词都感兴趣吗,包括经常被忽略的单词,如a、and、is等?你是否考虑过使用像Lucene这样的API或类似的东西来帮助你?我考虑每一个词,包括词尾。我没有考虑使用lucene。我不知道它是否有帮助,因为我正在MapReduce中实现它。但是无论如何,我希望看到解决方案,即使它已经在某个地方实现了。您想要基于所有计数的文档中的k个最不频繁的单词还是每个文档中的k个最不频繁的单词?无论如何,这在MapReduce中很容易实现,也许你应该告诉我们你遇到了什么问题。我不确定我是否理解这个问题,但我不认为它能更好。基本上你所说的DW是输入的大小,基本上你读每个单词,然后在O1中选择是否接受。因此,渐近复杂性与读取数据所需的复杂性相同。我不知道你如何在不读取所有输入数据的情况下解决这个问题。它可以通过使用比contains更有效的字符串搜索算法来改进,contains使用indexOf。。。也许可以尝试使用StringSearch,你是对的,非常好的主意!事实上,我并没有遵守文字的定义。我只是用它对单词进行排序,然后我只将单词保留在内存中,没有df,只关心它们的顺序。或者,我可以将单词在排序列表中的相对位置排名作为地图的值。现在速度快多了!我使用这篇文章对每个文档映射进行排序,我根据DFs:,为每个文档创建了一个映射。