我应该“编写一个方法,打印出数组中最常出现的前5个数字,以及每个数字的出现次数”我有一个方法打印出一个数组中每个条目的出现次数,我创建了另一个方法来打印数组中前5个出现次数。我能够以降序正确显示这些值,但我很难获得相同的键。例如,我的输出是“2发生:5次3发生:4次4发生:3次5发生:3倍6发生:2次”当它应该是“3发生:5倍9发生:4倍6发生3倍7发生3倍5发生2次”我如何修复我的方法以获得预期的输出?
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Random;
public class HW4 {
public static void main(String[] args) {
int[] a = getRandom(20, 1, 10);
System.out.println(Arrays.toString(a));
System.out.println();
occurrence(a);
System.out.println();
top5(a);
}
public static int[] getRandom(int n, int low, int high) {
long seed = 0;
Random random = new Random(seed);
random.setSeed(seed);
int[] result = new int[n];
for (int i = 0; i < n; i++)
result[i] = random.nextInt(high - low) + low;
return result;
}
public static void occurrence(int[] x) {
HashMap<Integer, Integer> occurrences = new HashMap<>();
for (int key : x) {
if (occurrences.containsKey(key)) {
occurrences.put(key, occurrences.get(key) + 1);
} else {
occurrences.put(key, 1);
}
}
for (int key : occurrences.keySet()) {
System.out.println(key + " occurs: " + occurrences.get(key) + " times");
}
}
public static void top5(int[] arr) {
HashMap<Integer, Integer> lookup = new HashMap<Integer, Integer>();
for (int key : arr) {
if (lookup.containsKey(key)) {
lookup.put(key, lookup.get(key) + 1);
} else {
lookup.put(key, 1);
}
}
ArrayList<Integer> keys = new ArrayList<>(lookup.keySet());
ArrayList<Integer> values = new ArrayList<>(lookup.values());
for (int i = 0; i < 5; i++) {
Collections.sort(values, Collections.reverseOrder());
System.out.println(keys.get(i) + " occurs: " + values.get(i) + " times");
}
}
}
5条答案
按热度按时间daolsyd01#
前两行创建直方图,即将每个值Map到其出现次数的Map。下一行获取条目流,这些条目将在下一行中按其值(即出现次数)按相反顺序排序。您只需要5个元素,因此结果被限制为5个,在最后一行中,结果输出格式良好。
ar7v8xwq2#
条目列表+排序
最简单的方法是使用
HashMap
计算阵列中每个数字的频率,正如您所做的那样。然后将所有Map条目转储到列表中,并按值对列表排序。我们需要
Comparator
来执行此排序。为此,我们可以使用Java 8方法Map.Entry.comparingByValue()
来获得比较器。并且作为最后一步,打印第一
5
元素。优先队列
更有效的方法是使用
PriorityQueue
,而不是对整个数据进行排序。第一步保持不变-生成一个频率图。
下一步是创建一个
PriorityQueue
,它将存储Map条目。为此,我们还需要一个比较器。然后迭代条目集,尝试将每个条目提供给队列。如果队列的大小等于
5
,并且下一个条目的值大于队列中最低值的数值(这将是PriorityQueue
的根元素的值),则需要删除队列的根元素。只要有空闲空间,就应将下一个条目添加到队列中(如果队列大小小于5
)。下面是它的实现方式:
ie3xauqp3#
如果您正在寻找使用Hashmap的方法,您可以这样做
对于java,结果通常需要非常大的函数lol。可能有一种更有效的方法,但这是我个人提出的
e1xvtsh34#
一旦创建了事件Map,
1.您可以创建一个最大密钥堆。您可以在最大堆中传递比较器,以根据事件Map中的值进行比较。
1.在此之后,您可以从maxHeap轮询5次
您可以更新top5函数,如下所示:
prdp8dxp5#
在这个答案中,我假设您至少有五个数字:
如果这个答案看起来太复杂,那么您可以将
minimumIndex
的计算分离成一个单独的方法,并使用两次。否则,它应该很容易应用,特别是因为还添加了注解。