[英]Word Frequency - HashMap or TreeMap
我需要制作一個計算文本中每個單詞頻率的程序,另外我需要能夠返回n個最常用單詞的列表(如果更多的單詞具有相同的頻率,則按字母順序排序)。 還有一個不計算的單詞列表(停用詞)。
總體來說哪種方法更有效?
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 <= m
且m <= k
,我們知道m log n <= k log m
,並且假設有大量重復或n
略小於m
, k + m log n <= k log m
,所以HashMap
通常是首選的選項。
停用詞:HashSet或regexp。
我會使用哈希映射來計算頻率計數:
所以你會做很多插入。 HashMap的總體插入成本: O(n) ,對於TreeMap: O(n log w) 。
散列映射的成本: O(w log w) ,加上提取開銷O(w) 。 即使TreeMap為零,對於大n , O(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.