AOE AOE - 23 days ago 12
Java Question

Sorting frequency of chars

I just made an algorithm that counts the frequency of chars in a String. What I am confused about is how to sort the frequency so the character with the greatest number of occurences is listed at the top, and the least at the bottom.

At first I tried having another variable 'fc' (for frequency counter) to coincide with my original counter variable 'k'. However I am stuck in the thought process of how to go about sorting this frequency, the fc var I made is just useless.

Thanks for any help provided!

Here is my code:

import java.io.*;
public class Freq
{
public static void main(String args[])throws IOException
{
//read input stream
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int ci,i,j,k,l,fc;l=0;
String str,str1;
char c,ch;
System.out.println("Enter your String");
str=in.readLine();
i=str.length();
//cycle through ASCII table chars and obtain chars typed
for(c='A';c<='z';c++)
{
k=0;
fc=0; //fc keeps count like k
for(j=0;j<i;j++)
{
ch=str.charAt(j);
if(ch==c)
k++;
fc=k-1; //was going to represent this counter for 'less than k'

}
if(k>0)
System.out.println("The character "+c+" has occured for "+k+" times");
}
}
}

Answer

You will need to store them all first. You can use a HashMap to store them all, it will also simplify your counting routine. Then Collections.sort on the entry set. You will need to make a Comparable> to compare the entry values for sorting.

Edited to add sample code....

    BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    System.out.println("Enter your String");
    String line = in.readLine();
    HashMap<Character,Integer> counts = new HashMap<>();
    for(char c : line.toCharArray()) {
        Integer count = counts.get(c);
        if (count == null) {
            count = 0;
        }
        counts.put(c, ++count);
    }
    List<Entry<Character,Integer>> list = new ArrayList<>(counts.entrySet());
    Collections.sort(list, new Comparator<Entry<Character,Integer>>() {
        @Override
        public int compare(Entry<Character, Integer> o1,
                Entry<Character, Integer> o2) {
            return o2.getValue() - o1.getValue();
        }
    });
    for(Entry<Character,Integer> entry : list) {
        System.out.println("The character "+entry.getKey() +" has occured for "+ entry.getValue()+" times");
    }