Reputation: 153
alright so im making a program that prints out how many times the numbers 0-9 were input, its supposed to go on forever, until the user types a negative number, then its gonna stop the program and print out the result, heres my code so far:
import java.util.Scanner;
public class opg33 {
public static void main(String args[]) {
System.out.println(1 + ":" + "\t" + "Integer 0-9");
Scanner keyboard = new Scanner(System.in);
int[] a = new int[10];
int counter = 0;
int input;
input = keyboard.nextInt();
boolean exit = true;
while (exit == true) {
counter++;
System.out.println((counter + 1) + ":" + "\t" + "Integer 0-9");
if (input > -1 && input < 10) {
a[input]++;
}
input = keyboard.nextInt();
if (input < 0) {
exit = false;
for (int i = 0; i < a.length; i++) {
System.out.print(i + ":");
for (int n = 0; n < a[i]; n++)
System.out.print("x");
System.out.println();
}
}
}
}
}
as you can see this program works perfectly fine, just as I wanted it to! the only question I have, is, how can I make it print out vertically like a bar graph (columns), instead of horizontally? thanks in advance!
Upvotes: 0
Views: 1147
Reputation: 347334
You mean something like...?
1: Integer 0-9
1
2: Integer 0-9
1
3: Integer 0-9
2
4: Integer 0-9
2
5: Integer 0-9
2
6: Integer 0-9
3
7: Integer 0-9
3
8: Integer 0-9
7
9: Integer 0-9
8
10: Integer 0-9
-1
x
x x x
x x x x x
0 1 2 3 4 5 6 7 8 9
The first thing you need to do is determine the max height of the chart...
// Calculate the required height...
/*
All this loop does, is loops through the array "a"
and finds the maximum value contained within,
this is the largest number of times the user
entered that value
The loop itself is just an enhanced "for-next-loop",
that is, it's a short cutted way of saying...
for (int index = 0; index < a.length; index++) {
int value = a[index];
...
}
*/
int maxFrequency = 0;
for (int value : a) {
// This is a really simply way to calculate the max value within
// range, it just says, return me the value which is the larger
// of two...
maxFrequency = Math.max(value, maxFrequency);
}
Next, you need to print each row of the chart, starting at the top and moving to the bottom. For each column, you need to determine if it has a value to be displayed within that row...
// This builds each row
for (int row = maxFrequency; row > 0; row--) {
// This is used instead of String concatenation (String + String)
// This is the preferred mechanism for doing String concatenation
// in loops as it uses less memory and will generally be faster...
StringBuilder sb = new StringBuilder(30);
// We need to inspect each value in the array to determine
// if we need to display something...
// The basic idea is, we will only start displaying "x"
// when the value in the array >= the row number...
for (int value : a) {
// This just appends each column value as
// required, prefixing and suffixing it with spaces
sb.append(" ");
if (value >= row) {
sb.append("x");
} else {
sb.append(" ");
}
sb.append(" ");
}
// Print the row...
System.out.println(sb.toString());
}
And finally, you need to print the footer...
StringBuilder sb = new StringBuilder(30);
for (int i = 0; i < a.length; i++) {
sb.append(" ").
append(i).
append(" ");
}
System.out.println(sb.toString());
The hows and why of StringBuilder
A book could be written on this subject, so the information provided here is just an overview...
StringBuilder
should be used, especially, when concatenating String
s in loops, basically because it reduces the number of temporary, short lived objects that are created and makes the process more efficient.
Normally the Java compiler will convert String
concatenation to use StringBuilder
internally, but because of the nature of loops, can't do so. In your case, it's probably not all that important, but in long running programs which might iterate through the loop, hundreds, thousands or even millions of time, it becomes a performance bottleneck, so it is a good habit to form.
Internally, a StringBuilder
is a self managed char
array, this is not particular important, but it's nice to know. When you use .append
, the StringBuilder
is taking the content, making space for it within it's internal buffer and writing out the content to it. It might sound like that's introducing it's own overheads and to a certain extent it is (you can do things to imittergate these), but it's less then having to run a garbage collection cycle...
toString
simply then converts the char
array to a String
object...
You can find more information at The StringBuilder Class
Upvotes: 2