首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在数组中打印前5位最常见的数字?

如何在数组中打印前5位最常见的数字?
EN

Stack Overflow用户
提问于 2022-09-17 16:52:58
回答 5查看 128关注 0票数 2

我应该“编写一个方法,打印出数组中最常见的前5个数字,以及每个数组的出现次数”,我有一个方法,它输出数组中每个条目的出现情况,并创建了另一个方法来打印数组中最常见的5个数字。我能够按降序正确地显示值,但我很难获得同样的键。例如,我的数组是7、8、5、3、9、3、3、9、4、7、3、6、9、3、2、9、6、5、7、6、3、3和3。对于top5方法,我的输出是"2 :5:5:4:3:3:5:3:6:2“,当它应该是"3 :5:9:4:6:3:3:5:2”时,我如何才能修复我的方法以获得预期的输出?

代码语言:javascript
运行
复制
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");
        }
    }
}
EN

回答 5

Stack Overflow用户

发布于 2022-09-17 18:33:43

代码语言:javascript
运行
复制
public static void top5(int[] arr) {
    IntStream.of(arr).boxed()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet().stream()
            .sorted((e1, e2) -> Long.compare(e2.getValue() , e1.getValue()))
            .limit(5)
            .forEach(e -> System.out.printf("%d occurs %d times%n", e.getKey(), e.getValue()));
}

前两行创建直方图,即映射每个值到其出现次数的地图。下一行将获得条目流,该流将按其值(即发生的数量)进行反向排序。您只需要5个元素,因此结果被限制为5,最后一行的结果被很好地格式化。

票数 1
EN

Stack Overflow用户

发布于 2022-09-17 19:08:30

条目列表+排序

最简单的方法是使用HashMap计算数组中每个数字的频率,就像您所做的那样。

然后将所有映射项转储到列表中,并按值对列表进行排序。我们需要一个Comparator来执行这个排序。为此,我们可以使用Java 8方法Map.Entry.comparingByValue()获得一个比较器。

作为最后一步,打印第一个5元素。

代码语言:javascript
运行
复制
public static void top5(int[] arr) {
    Map<Integer, Integer> lookup = new HashMap<>();
    for (int key : arr) {
        int value = lookup.getOrDefault(key, 0); // or lookup.merge(key, 1, Integer::sum); instead of these two lines
        lookup.put(key, value + 1);
    }
    
    List<Map.Entry<Integer, Integer>> sortedEntries = new ArrayList<>(lookup.entrySet());
    
    sortedEntries.sort(Map.Entry.<Integer, Integer>comparingByValue().reversed());
    
    for (int i = 0; i < 5; i++) {
        System.out.println(
            sortedEntries.get(i).getKey() + " occurs: " + 
            sortedEntries.get(i).getValue() + " times"
        );
    }
}

PriorityQueue

与其对整个数据进行排序,更好的方法是使用PriorityQueue

第一步保持不变-生成一个频率图。

下一步是创建一个存储地图条目的PriorityQueue。为此,我们还需要一个比较国。

然后遍历条目集,尝试将每个条目提供给队列。如果队列的大小等于5,且下一个条目的值大于队列中最低值的值(即PriorityQueue的根元素的值),则需要删除队列的根元素。只要队列有空闲空间(如果队列大小小于5),就应该将下一个条目添加到队列中。

以下是它的实现方式:

代码语言:javascript
运行
复制
public static void top5(int[] arr) {
    Map<Integer, Integer> lookup = new HashMap<>();
    for (int key : arr) {
        int value = lookup.getOrDefault(key, 0); // or lookup.merge(key, 1, Integer::sum); instead of these two lines
        lookup.put(key, value + 1);
    }
    
    Queue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>(
        Map.Entry.comparingByValue()
    );
    
    for (Map.Entry<Integer, Integer> entry: lookup.entrySet()) {
        if (queue.size() == 5 && queue.peek().getValue() < entry.getValue()) queue.poll();
        if (queue.size() < 5) queue.offer(entry)
    }
    
    while (!queue.isEmpty()) {
        Map.Entry<Integer, Integer> next = queue.poll();
        
        System.out.println(
            next.getKey() + " occurs: " +
            next.getValue() + " times"
        );
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-09-17 17:24:21

如果您正在寻找一种使用Hashmap的方法,您可以这样做

代码语言:javascript
运行
复制
public static void top5(int[] arr) {
        LinkedHashMap<Integer, Integer> lookup = new LinkedHashMap<>();
        for (int key : arr) {
            if (lookup.containsKey(key)) {
                lookup.put(key, lookup.get(key) + 1);
            } else {
                lookup.put(key, 1);
            }
        }
        Map<Integer, Integer> result = lookup.entrySet() /* sorts the linked_map by value */
                .stream()
                .sorted(Map.Entry.comparingByValue())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));

        List<Integer> key_in_order
                = new ArrayList<Integer>(result.keySet());  // convert to list

        /* reverse the key because it was backward compared to what you want */
        Collections.reverse(key_in_order);

        for (int i = 0; i < 5; i++) {
            System.out.println("key : "+String.valueOf(key_in_order.get(i)) + " value : " + result.get(key_in_order.get(i)) );
        }
    }

对于java来说,结果需要非常大的函数lol --可能有一种更有效的方法--但这正是我个人想出来的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73756799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档