yyzzer1234
yyzzer1234

Reputation: 153

How to print out columns instead of rows?

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

Answers (1)

MadProgrammer
MadProgrammer

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 Strings 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

Related Questions