Beginning Java (Histogram)
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
Comments
-
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 almost 15 yearsUnfortunately I can't compile it without your generator class.
-
Mohammad Taha almost 15 yearsand 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 almost 15 yearsHow can I make them the same, or at least not create the error? -Thanks,
-
Benzle almost 15 yearsThanks everyone so much, this has been a great first experience on stack overflow!
-
Andrei about 10 yearsCould you explain the code in a few words ? It will make your answer so much better and you could get more votes.
-
Amjad about 10 yearsI'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 about 10 yearsAdded your explanation to the answer. In the feature don't forget to explain your code :) Good job!