You know, it's nice to see code that does what it says, and a nice simple task that still requires some head scratching.... but I'll assume you're a Java beginner.
Basics
Going through some of the basic stuff...
- you have the
cont
variable declared as a static variable outside the method, but the only place it is used is inside the method. In this case, you should move the declaration inside the main
method. Also, nothing changes that state, so the program just runs, and runs, which is OK (as a beginner).
- you do not close the
input
Scanner. Again, this is probably because the program never completes, but there are nice ways in Java7 to make sure it happens neatly, and without much effort.
- you should probably validate the user input. If the user enters negative integers, it's actually OK (the program does nothing). More concerning is if the user enters 2000000000. You should set an upper bound.
- you call this shape a 'diamond' but it is actually a square. The width and height are the same number of characters. You only need one variable,
lines
or width
, not both.
- it is confusing that you have both
line
and lines
variable. There is no need for lines
if you use width
instead, so get rid of it (also since the user prompt is "Width:").
OK, that's some relatively simple stuff. Messing your code around using the above suggestions I get:
public static void main (String[] args) {
boolean cont = true;
try (Scanner input = new Scanner(System.in)) {
while (cont) {
System.out.print("Width: ");
int width = input.nextInt();
System.out.println();
if (width > 100) {
System.out.println("Width too wide, reducing to 100");
width = 100;
}
for (int line = 0; line < width; line++) {
for (int spaces = 0; spaces < Math.abs(line - (width / 2)); spaces++) {
System.out.print(" ");
}
for (int marks = 0; marks < width - 2 * (Math.abs(line - (width / 2))); marks++) {
System.out.print("x");
}
System.out.println();
}
System.out.println();
}
}
}
Algorithm
OK, now, some algorithmic things:
System.out.print(...)
and the println
variants, are actually really slow. Calling them from inside loops is a real problem for performance, and is a bad habit to learn. These methods lock the console output, and are not nice to other threads either. Where possible, you should always batch up the character printing in to a larger statement.
- Sometimes, taking stuff away is easier than adding it .... (cryptic hint).
We can solve a lot of the complexity in your loops by doing a couple of tricks. Here's a suggestion:
- Build up two Strings, one of spaces and the other of 'x' characters. Each should be at least as long as the longest value we will need.
- loop through the rows and use parts of each of the two above strings.
The logic is the exact same as yours except I have big things I use a part of, whereas you build it up bit by bit. The important part is the Math.abs(...) statements are identical to the previous version.... they are the limit to the values we build.
Here's a way to do it:
public static void main (String[] args) {
boolean cont = true;
try (Scanner input = new Scanner(System.in)) {
while (cont) {
System.out.print("Width: ");
int width = input.nextInt();
System.out.println();
if (width > 100) {
System.out.println("Width too wide, reducing to 100");
width = 100;
}
char[] spaces = new char[width / 2];
char[] exes = new char[width];
Arrays.fill(spaces, ' '); // now an array of spaces
Arrays.fill(exes, 'x'); // now an array of 'x'
for (int line = 0; line < width; line++) {
String pad = new String(spaces, 0, Math.abs(line - (width / 2)));
String fill = new String(exes, 0, width - 2 * (Math.abs(line - (width / 2))));
System.out.println(pad + fill);
}
System.out.println();
}
}
}
That's just something for you to think about.....