Lets say with the array:
array = {1,2,1,2,1,3,2,1};
I want the output to be:
2 pairs of number 1, 1 pair of number 2
For that I created a Hash table. The code :
class Trail{ static void countFreq(int arr[], int n) { Map<Integer, Integer> mp = new HashMap<>(); // Insert elements into HashTable while avoiding overwriting: for (int i = 0; i < n; i++) { // This part is to avoid overwriting: if (mp.containsKey(arr[i])) { mp.put(arr[i], mp.get(arr[i]) + 1); } else { mp.put(arr[i], 1); } } // Traverse through map and print frequencies for (Map.Entry<Integer, Integer> entry : mp.entrySet()) { System.out.println(entry.getKey() + " " + entry.getValue()); } } public static void main(String[] args) { int arr[] = {1,2,1,2,1,3,2,1}; int n = arr.length; countFreq(arr, n); } }
Not sure what to do next to print out the desired output. Been stuck in this simple part for a long time.
Advertisement
Answer
The calculation of frequencies seems to be fine, only printing part needs to be addressed. To get the number of pairs, divide the frequency by 2 (or shift right by 1), and skip if the pair count is 0 (according to the expected output).
Printing should be moved into a separate method:
static void printFreq(Map<Integer, Integer> mp) { boolean addComma = false; for (Map.Entry<Integer, Integer> entry : mp.entrySet()) { int pairs = entry.getValue() / 2; if (pairs < 1) { continue; // skip 0 pairs } if (addComma) { System.out.print(", "); } String p = pairs > 1 ? " pairs " : " pair "; System.out.print(pairs + p + "of number " + entry.getKey()); addComma = true; } System.out.println(); }
However, Stream API may be used for such tasks:
- use vararg
int ... arr
to pass the array of integer values in more convenient way (n
as the array length is redundant) - use
Collectors.groupingBy
andCollectors.summingInt
(orCollectors.counting
) to calculate raw frequency - calculate the number of pairs
- map each key-value pair into String
- join the strings using Collectors.joining
static void countFreq(int ... arr) { String message = Arrays.stream(arr) .boxed() .collect(Collectors.groupingBy( x -> x, Collectors.summingInt(x -> 1) )) // Map<Integer, Integer> .entrySet() .stream() .peek(e -> e.setValue(e.getValue() / 2)) .filter(e -> e.getValue() > 0) .map(e -> String.format("%d %s of number %d", e.getValue(), e.getValue() > 1 ? "pairs" : "pair", e.getKey() )) .collect(Collectors.joining(", ")); System.out.println(message); }
Output (in both cases):
2 pairs of number 1, 1 pair of number 2