繁体   English   中英

单词频率 - HashMap或TreeMap

[英]Word Frequency - HashMap or TreeMap

我需要制作一个计算文本中每个单词频率的程序,另外我需要能够返回n个最常用单词的列表(如果更多的单词具有相同的频率,则按字母顺序排序)。 还有一个不计算的单词列表(停用词)。

  1. 什么结构用于停用词
    • 我认为HashSet效率最高
  2. 用于单词和频率映射的结构
    • HashMap对于添加单词会更有效,但需要排序,TreeMap需要登录时间来插入单词,但单词可以按频率排序

总体来说哪种方法更有效?

PS @Moderators我知道有一个类似的问题 ,但我有一个不同的约束,需要不同的结构。

让我们假设总共有k单词和m不同的单词,你想要n最常用的单词。

TreeMap的

由于地图中永远不会超过m单词,因此每个更新/插入将花费O(log m) ,总运行时间为O(k log m)

HashMap中

每次更新/插入将花费预期的O(1) ,对所有单词取O(k)

然后,由于地图中将有m单词,因此排序将采用O(m log m)

但是我们可以做得比排序更好 - 我们可以遍历HashMap并维护n最常用词的PriorityQueue )(主要按频率排序,其次按字母顺序排序)。 每次插入堆后,如果大小大于n ,我们删除最不频繁的单词。 这将花费O(m log n)

因此,预计总运行时间为O(k + m log n)

对照

由于n <= mm <= k ,我们知道m log n <= k log m ,并且假设有大量重复或n略小于mk + m log n <= k log m ,所以HashMap通常是首选的选项。

停用词:HashSet或regexp。

我会使用哈希映射来计算频率计数:

  1. 你的词语w是(或多或少)有限的
  2. 您的输入大小n (可能)是无界的

所以你会做很多插入。 HashMap的总体插入成本: O(n) ,对于TreeMap: O(n log w)

散列映射的成本: O(w log w) ,加上提取开销O(w) 即使TreeMap为零,对于大nO(w log w)也会变得非常小。

请注意,一般情况下,没有保证的方法可以在没有基准测试的情况下解决这个问题。

您可以对计数/单词的最终HashMap<String, Integer>执行单次传递,并使用TreeMap<Integer, List<String>>TreeMap.firstKey()TreeMap.size()方法计算前N个话。 练习留给读者。 或者(或更好),使用像这样的红黑树,当您发现较大的计数时(当您的前N中树的大小> N时),您不断修剪最低计数节点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM