Java 巨大哈希表排序-值的数量-553685
我创建了一个hashmap来存储多个文件中出现的单词,比如10000个文本文件。然后我想从hashmap中对它们进行排序,并打印出前10个单词。Hashmap定义为Java 巨大哈希表排序-值的数量-553685,java,sorting,hashtable,Java,Sorting,Hashtable,我创建了一个hashmap来存储多个文件中出现的单词,比如10000个文本文件。然后我想从hashmap中对它们进行排序,并打印出前10个单词。Hashmap定义为 Hashtable <String, Integer> problem1Counter = new Hashtable<String, Integer> (); int kk=0; 字符串ii=null for (int jj = 0; jj < valuesProblem1.le
Hashtable <String, Integer> problem1Counter = new Hashtable<String, Integer> ();
int kk=0;
字符串ii=null
for (int jj = 0; jj < valuesProblem1.length ; jj++){
for (int bb = 0; bb < valuesProblem1.length; bb++){
if(valuesProblem1[jj] < valuesProblem1[bb]){
kk = valuesProblem1[jj];
ii = keysProblem1[jj];
valuesProblem1[jj] = valuesProblem1[bb];
keysProblem1[jj] = keysProblem1[bb];
valuesProblem1 [bb] = kk;
keysProblem1 [bb] = ii;}}}
for(int jj=0;jj
因此,当哈希表的值超过553685时,上述方法不起作用。那么,有人能建议并展示一种更好的方法来对它们进行排序吗?我是java的新手,但在actionscript工作过,所以我觉得有点舒服。
谢谢。- 创建实现可比较的内部类单词
- 重写public int compareTo(单词w)以使其使用引用
- 创建一个HashMap大小的单词数组
- 在HashMap中迭代填充数组
- 在数组上调用Arrays.sort
或者,因为您只需要前10名,所以您可以反复浏览您的单词,并在继续操作时维护前10名列表。当您拆分
键和值时,您的问题就开始了,并尝试将每个索引中的内容保持连接。相反,让它们保持耦合,并对java提供的Map.Entry
对象进行排序
我不确定这是否可以编译,但它应该给你一个开始
// HashMap and Hashtable are very similar, but I generally use HashMap.
HashMap<String, Integer> answers = ...
// Get the Key/Value pairs into a list so we can sort them.
List<Map.Entry<String, Integer>> listOfAnswers =
new ArrayList<Map.Entry<String, Integer>>(answers.entrySet());
// Our comparator defines how to sort our Key/Value pairs. We sort by the
// highest value, and don't worry about the key.
java.util.Collections.sort(listOfAnswers,
new Comparator<Map.Entry<String, Integer>>() {
public int compare(
Map.Entry<String, Integer> o1,
Map.Entry<String, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
// The list is now sorted.
System.out.println( String.format("Top 3:\n%s: %d\n%s: %d\n%s: %d", +
listOfAnswers.get(0).getKey(), listOfAnswers.get(0).getValue(),
listOfAnswers.get(1).getKey(), listOfAnswers.get(1).getValue(),
listOfAnswers.get(2).getKey(), listOfAnswers.get(2).getValue()));
//HashMap和Hashtable非常相似,但我通常使用HashMap。
HashMap答案=。。。
//将键/值对放入列表中,以便我们可以对它们进行排序。
答案列表=
新的ArrayList(answers.entrySet());
//我们的比较器定义如何对键/值对进行排序。我们按顺序分类
//最高值,不必担心密钥。
java.util.Collections.sort(listOfAnswers,
新比较器(){
公共整数比较(
地图条目o1,
地图入口(o2){
返回o2.getValue()-o1.getValue();
}
});
//列表现在已排序。
System.out.println(String.format(“前三名:\n%s:%d\n%s:%d\n%s:%d”),+
ListOfAnwers.get(0).getKey(),ListOfAnwers.get(0).getValue(),
ListOfAnwers.get(1).getKey(),ListOfAnwers.get(1).getValue(),
get(2.getKey(),ListoFaswers.get(2.getValue());
要获得更好的排序方法,我可以这样做:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
HashMap<String, Integer> counter = new HashMap<String, Integer>();
// [... Code to populate hashtable goes here ...]
//
// Extract the map as a list
List<Map.Entry<String, Integer>> entries = new ArrayList<Map.Entry<String, Integer>>(counter.entrySet());
// Sort the list of entries.
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> first, Entry<String, Integer> second) {
// This will give a *positive* value if first freq < second freq, zero if they're equal, negative if first > second.
// The result is a highest frequency first sort.
return second.getValue() - first.getValue();
}
});
// And display the results
for (Map.Entry<String, Integer> entry : entries.subList(0, 10))
System.out.println(String.format("%s: %d", entry.getKey(), entry.getValue()));
}
}
import java.util.ArrayList;
导入java.util.Collections;
导入java.util.Comparator;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Map.Entry;
公共班机{
/**
*@param args
*/
公共静态void main(字符串[]args){
HashMap计数器=新HashMap();
//[…填充哈希表的代码位于此处…]
//
//将地图提取为列表
列表条目=新的ArrayList(counter.entrySet());
//对条目列表进行排序。
Collections.sort(条目,新的Comparator(){
@凌驾
公共整数比较(第一个条目,第二个条目){
//如果first freqsecond,则为负。
//结果是频率最高的第一种排序。
返回second.getValue()-first.getValue();
}
});
//并显示结果
for(Map.Entry:entries.subList(0,10))
System.out.println(String.format(“%s:%d”、entry.getKey()、entry.getValue());
}
}
编辑解释此操作的原因
您的原始算法看起来像的变体,它是一个O(n^2)算法。您的变体也会进行大量额外的交换,因此速度相当慢
由于是O(n^2),如果将问题大小乘以10,通常需要100倍的时间才能运行。对50万个元素进行排序需要进行2500亿次比较,其中许多将导致互换
Collections#sort中的内置排序算法是的一个闪电般快速的变体,它在O(n.log(n))时间内运行。这意味着每次你把问题的大小乘以10,只需要30倍的时间。排序50万个元素只需要进行大约1000万次比较
这就是为什么有经验的开发人员会建议您尽可能使用库函数的原因。编写自己的排序算法对学习来说是一件好事,但要实现一个像库中一样快速灵活的算法需要大量的工作。你说的“不工作”是什么意思?它会引发异常吗?如果是,那是什么?顺便问一下,您是否需要同步Problem1计数器?如果没有,您可能会发现HashMap
更合适。@Martin它一直在运行,我等了几分钟多。一点错误都没有,所以我想把它改进得更好。听起来好像太慢了。你能在两个for循环之间放一个System.out.println(Integer.toString(jj))来确认吗?@martini添加了print语句-它显示1、2、3、4,但速度非常慢。是否有任何java内存设置我应该考虑?哈哈1,阅读你让我意识到我有O1-O2当我需要O2 -O1!这是处理hashmap的有效方法。谢谢@科里肯德尔:我认为你不需要实现比较器。你呢?您将得到隐式Object.equals,而不使用它(它进行引用比较)。不过,我对Java还是相当陌生,所以我想知道我是否弄错了。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
HashMap<String, Integer> counter = new HashMap<String, Integer>();
// [... Code to populate hashtable goes here ...]
//
// Extract the map as a list
List<Map.Entry<String, Integer>> entries = new ArrayList<Map.Entry<String, Integer>>(counter.entrySet());
// Sort the list of entries.
Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Entry<String, Integer> first, Entry<String, Integer> second) {
// This will give a *positive* value if first freq < second freq, zero if they're equal, negative if first > second.
// The result is a highest frequency first sort.
return second.getValue() - first.getValue();
}
});
// And display the results
for (Map.Entry<String, Integer> entry : entries.subList(0, 10))
System.out.println(String.format("%s: %d", entry.getKey(), entry.getValue()));
}
}