AdiBoy
AdiBoy

Reputation: 155

Count occurrences & print highest occurred char 'n' times

I was trying to solve some programs, I came across this interesting one, where we need to print the highest occurred character n times & likewise for other characters.

Ex: Input string : "please stay hydrated" Output string : "aaaeeettyysplhdr"

I was only able to solve half way, where we print the highest occurred character & the times it has occurred using a HashMap.

   public static void repeatedChar(String str) {

        char[] chars = str.toCharArray();
        Map<Character, Integer> map = new HashMap<>();

        for (Character c : chars) {
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            } else {
                map.put(c, 1);
            }
        }

        //Now To find the highest character repeated

        int max = 0;
        //setting to a by default
        char maxCharacter = 'a';

        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            System.out.println("Key = " + entry.getKey() + ": Value " + entry.getValue());
            if (max < entry.getValue()) {
                max = entry.getValue();
                maxCharacter = entry.getKey();
            }
        }

        System.out.println("Max Character = " + maxCharacter + " Max Count : " + max);
    }

This currently prints the highest occured character & the number of times that character has occurred. Can someone please let me know how to proceed further? Thanks

Upvotes: 0

Views: 100

Answers (1)

Eritrean
Eritrean

Reputation: 16498

In order to get the desired output you need to sort your map by value. But since a hashmap is not meant to be sorted, but accessed fast, you could add all entries to a list and sort the list. Something like:

import java.util.Map.Entry;
import java.util.Comparator;


....

public static void repeatedChar(String str) {
    char[] chars = str.toCharArray();
    Map<Character, Integer> map = new HashMap<>();

    for (Character c : chars) {
        if (map.containsKey(c)) {
            map.put(c, map.get(c) + 1);
        } else {
            map.put(c, 1);
        }
    }

    //add map entries to list
    List<Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
    //sort entries by value descending
    list.sort(Entry.comparingByValue(Comparator.reverseOrder()));

    //print
    for (Entry<Character, Integer> entry : list) {
        for (int i = 0; i < entry.getValue(); i++){
            System.out.print(entry.getKey());
        }
    }
}

and if you fancy a stream approach:

import java.util.Comparator;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

....


public static void repeatedCharWithStreams(String str) {
    String output =
            Pattern.compile("")
                    .splitAsStream(str)
                    .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
                    .entrySet().stream()
                    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                    .map(e -> e.getKey().repeat(e.getValue().intValue()))
                    .collect(Collectors.joining());

    System.out.println(output);
}

Upvotes: 2

Related Questions