M.Ayzaz
M.Ayzaz

Reputation: 3

Find the second most frequent character in string using HashMap

I am trying to find the second most frequent character in a string. below is my code

public class secondCommonAlpha {

    public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {
               second = first;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);
               ans = c;
           }
       }
        return ans;
    }

    public static void main(String[] args) {
        secondCommonAlpha o = new secondCommonAlpha();
        System.out.println(o.secondCommon("bananassss"));
    }
}

its not working in third iteration. How can I fix and optimize this code?

EDIT

I have use two character variables to get the job done.

public Character secondCommon(String str)
    {
        Character ans = null;
        int first = 0, second = 0;
        Character firstChar = null,secondChar = null;
        HashMap<Character,Integer> counter = new HashMap<>();
        for(char c: str.toCharArray())
        {
            if(!counter.containsKey(c))
            {
                counter.put(c,1);
            }
            else
            {
                counter.put(c,counter.get(c) + 1);
            }
        }
        System.out.println(counter);
       for (char c: counter.keySet())
       {
           if(counter.get(c) > first)
           {

               second = first;
               secondChar = firstChar;
               firstChar = c;

               first = counter.get(c);
           }
           else
               if(counter.get(c) > second && counter.get(c) < first)
           {
               second = counter.get(c);

               secondChar = c;
           }
       }
        return secondChar;
    }

it is working fine now but I guess this code can be optimize.

Upvotes: 0

Views: 3549

Answers (1)

theawesometrey
theawesometrey

Reputation: 428

Here I have written a generic implementation that will given you the n most common character. In your case you could specify 2 as shown in the example main.

The answer is accomplished through sorting the set of map entries in descending order by the number of occurrences(value of the entry) and then picking n-1 (since base zero) indexes from the start of the list.

public static char nMostCommon(String str, int n) {
    Map<Character, Long> counter = str.chars()
        .mapToObj(c -> (char) c)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    if (counter.size() < n) {
        throw new IllegalArgumentException("Not enough different characters.");
    }
    return counter.entrySet().stream()
        .sorted(Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()))
        .map(Map.Entry::getKey)
        .collect(Collectors.toList())
        .get(n - 1);
}

public static void main(String[] args) {
    System.out.println(nMostCommon("bananassss", 2));
}

Upvotes: 1

Related Questions