javaarraysstringintegerhistogram

Making a Histogram using an Array of integers


I’m trying to make a method that takes a String and then fills an array based on the frequency of letters in the string where the array[0] is the number of A’s etc. Then it takes the array and prints out a histogram with all the letters with an asterisk above them in columns for each time a letter appears in the string. I was able to code the part that gets the amount of each letter in a string but I have no idea how to print out the histogram.

void drawHistogram() {
    int[] frequency = new int[26];
    for (int i = 0; i < text.length(); i++) {
        if (Character.isLetter(text.charAt(i))) {
            frequency[Character.getNumericValue(Character.toLowerCase(text.charAt(i))) - 10] += 1;
        }
    }
}

text is a string variable from the class.

For example, if text = "I love problem-solving.", the program should print this histogram

                      *     *   
        *       *     *     *             *           
  *     *   *   *     * * * * *   * *     *       
---------------------------------------------------
a b c d e f g h i j k l m n o p q r s t u v w x y z

There should be one asterisk above b, g, m, n, p, r and s. Two above e, i and v. Three above l and o.


Solution

  • In order to print the histogram as columns, with the letters below the columns, you first need to get the frequencies of each letter and also find the maximum frequency. Then you iterate through the letters and if that letter's frequency is not less than the maximum frequency, print a *, otherwise print a space. Then reduce the maximum by one and repeat – until the maximum reaches zero.

    public class Histogram {
        public static void main(String[] args) {
            String text = "I love problem-solving.";
            int[] frequency = new int[26];
            int max = 0;
            for (int i = 0; i < text.length(); i++) {
                if (Character.isLetter(text.charAt(i))) {
                    int ndx = Character.getNumericValue(Character.toLowerCase(text.charAt(i))) - 10;
                    frequency[ndx] += 1;
                    if (frequency[ndx] > max) {
                        max = frequency[ndx];
                    }
                }
            }
            for (int i = max; i > 0; i--) {
                for (int j = 0; j < frequency.length; j++) {
                    if (frequency[j] >= i) {
                        System.out.print("*");
                    }
                    else {
                        System.out.print(" ");
                    }
                    System.out.print(" ");
                }
                System.out.println();
            }
            System.out.println("-".repeat(51));
            System.out.println("a b c d e f g h i j k l m n o p q r s t u v w x y z");
        }
    }
    

    Here is the output:

                          *     *                       
            *       *     *     *             *         
      *     *   *   *     * * * * *   * *     *         
    ---------------------------------------------------
    a b c d e f g h i j k l m n o p q r s t u v w x y z
    

    I suggest that you step through the code with a debugger in order to better understand how it works.