Beginning Java (Histogram)

10,782

Solution 1

You need to remove the semicolon from the end of line 43:

if(generate[i] >= imin && generate[i] < imax);

The semicolon causes your if block to be empty. As a consequence, the line resulting in the exception is executed unconditionally.

Once you address that issue, here are a few hints to get you started on the further debugging of your code:


Take a look at the termination condition of your inner loop:

for (int j = 0; j<generate.length; j++)

You are iterating over the generated numbers in your outer loop; so you should be iterating over the intervals in your inner loop to determine the interval to which each generated number belongs.


Take a look at the code you are using to determine the bounds of the current interval in your loop:

double imin = mins+j*intervalWidth;
double imax = max +j*(intervalWidth);

These lines need to be modified to yield the correct values. Do a bit of 'pencil-and-paper debugging' to determine why they are currently in error.


I will leave the rest as an exercise for the reader for now. I will check back in later to see if you need any further assistance.

Solution 2

Since I was feeling generous on a Saturday I tried it out and rewrote your loop.

for (int j=0; j < generate.length; j++) {
    for(int i = 0; i < intervals; i++) {
        double imin = mins + i * intervalWidth;
        double imax = mins + (intervalWidth) * (i + 1);
        if(i == intervals - 1) imax = Double.POSITIVE_INFINITY;
        if(i == 0) imin = Double.NEGATIVE_INFINITY;

        if (generate[j] >= imin && generate[j] < imax) {
            intervalValue[i]++;
            break;
        }
    }
}

The infinity stuff is to catch the min and maxes in the histogram.

Solution 3

This will give you a very nice (basic) looking histogram. Try it

import java.util.HashMap;
import java.util.Map;

public class Histogram {
    public static void main(String[] args) {
        int[] age = { 25, 26, 33, 26, 27, 21, 26, 33, 21, 33, 21, 38, 19, 19};


        HashMap<Integer, Integer> m = new HashMap<Integer, Integer>();

        for (int i = 0; i < age.length; i++) {
            int c = 0;

            for (int j = 0; j < age.length; j++) {
                if (age[i] == age[j]) {
                    c++;
                }
            }
            m.put(age[i], c);

        }

        System.out.println("Histogram\n------------");
        for (Map.Entry<Integer, Integer> entry : m.entrySet()) {
            int key = entry.getKey();
            int value = entry.getValue();
            System.out.printf("%3d | ", key);
            for (int i = 0; i < value; i++) {
                System.out.print("=");
            }
            System.out.print(" " + value);
            System.out.println();
        }

    }

Outout:

Histogram
------------
 33 | === 3
 19 | == 2
 21 | === 3
 38 | = 1
 25 | = 1
 26 | === 3
 27 | = 1

I'm using HashMap to keep two related values namely the an array element and its frequency (how frequently it appears).

Then a nested loops to loop by each element along the array and count its frequency by using c variable.

After that I print it with for-each loop and normal loop

Share:
10,782
Benzle
Author by

Benzle

CSE beginner

Updated on June 14, 2022

Comments

  • Benzle
    Benzle about 2 years

    I'm taking a beginner Java class, with the assignment to create a histogram program with the following output: (100 and 10 are user inputs).

    How many numbers? 100 How many intervals? 10

    Histogram
    --------------------------------------------------------
      1 ****(4)
      2 ******(6)
      3 ***********(11)
      4 *****************(17)
      5 **************************(26)
      6 *************************(25)
      7 *******(7)
      8 ***(3)
      9 (0)
     10 *(1)
    --------------------------------------------------------
    

    My code is giving the following output however, can anyone help me point out what is going wrong, thanks so much.

    How Many Numbers? 10
    How Many Intervals? 10
    
    Histogram
    --------------------------------------------------------
     1 **********(10)
     2 **********(10)
     3 **********(10)
     4 **********(10)
     5 **********(10)
     6 **********(10)
     7 **********(10)
     8 **********(10)
     9 **********(10)
     10 **********(10)
    

    For the input, 100 and 10 I get the error message:

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 at Lab6.main(Lab6.java:44) I marked Line 44 below.

    Which links to this code;

                 intervalValue[j]++;
    

    I'm not sure how to attach the generator (.jar) file, it is supposed to just generate the random #'s for us. Thanks again.

    mport java.util.Scanner;
    
    public class Lab6 {
    
        public static void main(String[] args) {
    
            int numbers, intervals;
            double intervalWidth;
    
            double max, mins, range;
    
            Scanner keyboard = new Scanner(System.in);
    
            System.out.print("How Many Numbers? ");
    
            numbers = keyboard.nextInt();
    
            System.out.print("How Many Intervals? ");
    
            intervals = keyboard.nextInt();
    
            double [] generate = new double[numbers];
    
            generate = randomGenerator(numbers);
    
            max = maximum(generate);
    
            mins = minimum(generate);
    
            range = max - mins;
    
            intervalWidth = range / intervals;
    
            int [] intervalValue = new int[intervals];
    
            for (int i=0; i < generate.length; i++) {
    
                for (int j = 0; j<generate.length; j++){
                    double imin = mins+j*intervalWidth;
                    double imax = max +j*(intervalWidth);
                    if(generate[i] >= imin && generate[i] < imax)
                        intervalValue[j]++;         //LINE 44
                }
            }
    
            System.out.println("Histogram");
    
            System.out.println("--------------------------------" +
                               "------------------------");
    
            for (int a=0; a < intervalValue.length; a++) {
    
                System.out.print(" " + (a+1) + " ");
    
                for (int b=0; b < intervalValue[a]; b++) {
                    System.out.print("*"); 
                }
    
                System.out.println("(" + intervalValue[a] + ")");
            }
        }
    
        private static double [] randomGenerator(int number) {
            double [] generate;
    
            generate = Generator.getData(number);
    
            return generate; 
        }
    
        private static double maximum(double [] a) {
    
            double max = a[0];
    
            for (int i = 1; i < a.length; i++) {        
                if (a[i] > max) {
                    max = a[i];
                }         
            }
    
            return max;
        }
    
        private static double minimum(double [] a) {
    
            double mins = a[0];
    
            for (int i = 1; i < a.length; i++) {
                if (a[i] < mins) {
                    mins = a[i];
                }
            }
    
            return mins;
        }
    }
    
    • Kekoa
      Kekoa almost 15 years
      Unfortunately I can't compile it without your generator class.
    • Mohammad Taha
      Mohammad Taha almost 15 years
      and you might want to consider using a code formatter (eclipse has one built in) also don't try to post binary files' content. It doesn't help :)
  • Benzle
    Benzle almost 15 years
    How can I make them the same, or at least not create the error? -Thanks,
  • Benzle
    Benzle almost 15 years
    Thanks everyone so much, this has been a great first experience on stack overflow!
  • Andrei
    Andrei about 10 years
    Could you explain the code in a few words ? It will make your answer so much better and you could get more votes.
  • Amjad
    Amjad about 10 years
    I'm using HashMap to keep two related values namely the an array element and its frequency (how frequently it appears). Then a nested loops to loop by each element along the array and count its frequency by using "c" variable. After that I print it with enhanced for loop and normal loop
  • Andrei
    Andrei about 10 years
    Added your explanation to the answer. In the feature don't forget to explain your code :) Good job!