Home > OS >  How do I print the top 5 most occurring numbers in an array?
How do I print the top 5 most occurring numbers in an array?

Time:09-18

I'm supposed to "Write a method that prints out the top 5 most commonly occurring numbers in an array along with the count of occurrences for each" I have a method that prints out the occurrence of each entry in an array and I created another method to print the top 5 occurrences in the array. I'm able to get the values to display correctly in descending order but I'm having trouble getting the keys to do the same. For Example, my output is "2 occurs: 5 times 3 occurs: 4 times 4 occurs: 3 times 5 occurs: 3 times 6 occurs: 2 times" when it should be "3 occurs: 5 times 9 occurs: 4 times 6 occurs: 3 times 7 occurs: 3 times 5 occurs: 2 times" How can I fix my method to get the expected output?

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");
        }
    }
}

CodePudding user response:

If you're looking for a method using Hashmap, you could do that

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)) );
        }
    }

As for often with java, the result requires very big function lol There's probably a more efficient way but that's what I've come up with personally

CodePudding user response:

Once you have created occurrences map,

  1. you can create one max heap of the keys. You can pass comparator in max heap to compare based on values from occurrences map.
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a,b)->occurrences.get(b)-occurrences.get(a))
  1. after this you can just poll from maxHeap for 5 times
for(int i=0;i<5;i  ){
  if(!maxHap.isEmpty()){
    System.out.println(maxHeap.poll());
  }
}

You can update your top5 function as below:

public static void top5(Map<Integer, Integer> occurrences) {
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> occurrences.get(b) - occurrences.get(a));
        maxHeap.addAll(occurrences.keySet());
        System.out.println("top 5");
        for (int i = 0; i < 5; i  ) {
            if (!maxHeap.isEmpty()) {
                System.out.println(maxHeap.peek()   "  occurs: "   occurrences.get(maxHeap.poll())   " times");
            }
        }
    }
  • Related