单词频率 - HashMap或TreeMap

时间:2013-11-26 13:23:46

标签: java data-structures map hashmap treemap

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

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

    P.S。 @Moderators我知道有一个类似的question,但我有一个不同的约束,需要不同的结构。

3 个答案:

答案 0 :(得分:2)

我们假设总共有k个单词和m个不同的单词,您希望n最常用的单词。

<强> TreeMap的

由于地图中永远不会超过m个字词,因此每次更新/插入操作都需O(log m),总运行时间为O(k log m)

<强> HashMap中

每次更新/插入都需要花费O(1)的费用,所有字词都会O(k)

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

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

因此,预计总运行时间为n <= m

<强>比较

m <= km log n <= k log m以来,我们知道n,并且假设有大量重复项或m略小于k + m log n <= k log m,{ {1}},因此HashMap通常是首选选项。

答案 1 :(得分:0)

停用词:HashSet或regexp。

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

  1. 您的词语 w 是(或多或少)有限的
  2. 您的输入尺寸 n (可能)无界限
  3. 所以你会做很多插入。 HashMap的总体插入成本: O(n),对于TreeMap: O(n log w)

    对哈希映射的成本进行排序: O(w log w),以及提取开销 O(w)。即使TreeMap为零, O(w log w)对于大型 n 也会变得非常小。

    请注意,一般情况下,如果不对两者进行基准测试,都无法保证解决这个问题。

答案 2 :(得分:0)

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