我正在寫一個Java程序,用於解析文本文件中的所有單詞,然後將它們添加到HashMap中。我需要計算文件中包含多少個不同的單詞。我還需要計算出最高的計數單詞。 HashMap由映射到一個整數的每個單詞組成,該整數表示單詞出現的次數。類似HashMap但排序?
有沒有像HashMap這樣可以幫我排序呢?
我正在寫一個Java程序,用於解析文本文件中的所有單詞,然後將它們添加到HashMap中。我需要計算文件中包含多少個不同的單詞。我還需要計算出最高的計數單詞。 HashMap由映射到一個整數的每個單詞組成,該整數表示單詞出現的次數。類似HashMap但排序?
有沒有像HashMap這樣可以幫我排序呢?
它看起來像commons collections庫中的TreeBag
類可能會做你想做的。它跟蹤一個對象有多少個副本添加到包中,並按count的升序對它們進行排序。要獲得最高計數項目,請調用last()
方法。有一點需要注意的是,commons collections的東西還沒有更新到使用泛型,所以你可能會得到大量的編譯器警告。
手工的方式來做到這一點是如下:
word
和count
字段創建一個複合字計數類。正是我所想的。 – Esko 2009-12-01 20:15:00
你可以使用一個HashMultiset從google-collections:
import com.google.common.collect.*;
import com.google.common.collect.Multiset.Entry;
...
final Multiset<String> words = HashMultiset.create();
words.addAll(...);
Ordering<Entry<String>> byIncreasingCount = new Ordering<Entry<String>>() {
@Override public int compare(Entry<String> a, Entry<String> b) {
// safe because count is never negative
return left.getCount() - right.getCount();
}
});
Entry<String> maxEntry = byIncreasingCount.max(words.entrySet())
return maxEntry.getElement();
編輯:哎呀,我還以爲你只想要一個最常見的詞。但它聽起來像你想要的幾個最常見的 - 所以,你可以用sortedCopy
替換max
,現在你有一個所有條目的順序列表。
要查找的不同單詞的數量:words.elementSet().size()
+1:對於Google收藏集! – 2009-12-05 17:35:58
YourBean implements Comparable<YourBean>
這個答案是非常不完整的... – 2009-12-01 20:33:50
樹形圖不能按值排序!所以這不是正確的數據結構。 – 2012-02-22 12:25:14
爲計數,東東的Set中的單詞並計算完成後的大小。
對於最高值,迭代所有條目並保留具有最高值的鍵。
如果要按字排序Map,則TreeMap是Java內置答案。您可以確保您的Word對象是Comparable或提供自定義比較器。
SortedMap<Word,Integer> map = new TreeMap<Word,Integer>();
...
for all words {
Integer count = map.get(word);
if (count == null) count = 0;
map.put(word, count+1);
}
如果你想按頻率排序,那麼在所有的單詞已經被計數之後,你會更好的做到這一點。排序後的集合不會通過外部更改讓他們的排序搞砸。按頻率排序需要其他人發佈的複合詞+計數對象。
這使得地圖中的單詞按照字典順序排列,但不幸的是它們根本不按頻率排序。 – bchurchill 2013-01-14 11:31:32
你檢出了java.util.PriorityQueue嗎?PriorityQueue基本上是一個優先級映射到每個元素的列表(由非同步優先級堆實現)。每當你讀入一個新字符串時,如果它已經存在(對數時間),你可以將它加入或增加1。目前的支票是在線性時間,最後這將是非常容易使用。要獲得顯示頻率最高的數字,只需在每次完成時輪詢()!
編輯標準的PriorityQueue不允許您直接編輯優先級,因爲它需要一個比較器。你會用一個簡單的哈希實現什麼like this
更好這裏最普遍的回答的一個Groovy版本這個問題:
List leastCommon(Multiset myMultiset, Integer quantity)
{
Ordering<Multiset.Entry<String>> byIncreasingCount = new Ordering<Multiset.Entry<String>>() {
@Override public int compare(Multiset.Entry<String> a, Multiset.Entry<String> b) {
return a.getCount() - b.getCount() }
}
maxIndex = Math.min(quantity, myMultiset.entrySet().size() - 1)
return byIncreasingCount.sortedCopy(myMultiset.entrySet()).subList(0, maxIndex)
}
List mostCommon(Multiset myMultiset, Integer quantity)
{
Ordering<Multiset.Entry<String>> byDecreasingCount = new Ordering<Multiset.Entry<String>>() {
@Override public int compare(Multiset.Entry<String> a, Multiset.Entry<String> b) {
return b.getCount() - a.getCount() }
}
maxIndex = Math.min(quantity, myMultiset.entrySet().size() - 1)
return byDecreasingCount.sortedCopy(myMultiset.entrySet()).subList(0, maxIndex)
}
沒有標準的集合,我知道的是解決這個問題。那裏有幾個詞?如果你可以忍受開銷,最容易實現的就是使用HashMap,然後把這些單詞與出現在列表中並對其進行排序。 – Buhb 2009-12-01 20:07:02
想想吧,我在大學裏得到了這個確切的任務,我們必須在nlog(n)中解決它。我上面的建議管理着這一點。 – Buhb 2009-12-01 20:12:51
你想按字還是按頻率對地圖進行排序? – PSpeed 2009-12-01 21:57:23