我正在写一个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