tags:

views:

114

answers:

4

I'm trying to output a square of X's using an array. The diagonals of the square will be filled with 'X' and the empties will be filled with spaces '_'.

Here's the code I got:

public static char[][] square(int z) {
    int size=5;
    char[][] myArr = new char[size][size];
    for (int c=0;c<size;c++)
        myArr[c][c]='X';
    for (int r=0;r<size;r++)
    {
        for (int col=size-1;col>=0;col--)//put X
        {
            myArr[r][col]='X';
        }
    }
    for(int count=0;count<size;count++){
        if (myArr[count][count]!='X')
            myArr[count][count]=' ';
    }

    return myArr;

}

This should be working-I ran it manually on paper and everything should have been fine. What can the problem be?

+4  A: 

The problem is probably, that here:

for (int r=0;r<size;r++)
{
    for (int col=size-1;col>=0;col--)//put X
    {
        myArr[r][col]='X';
    }
}

you are itering over the whole square (size * size) and not just drawing the Northeast - Southwest diagonal.

Try to replace it with this:

for (int r=0;r<size;r++)
{
    myArr[r][size - r] = 'X'
}

EDIT: To make your code little bit compacter:

public static char[][] square(int size) {
    char[][] myArr = new char[size][size];
    for (int c = 0; c < size; c++) {
        for (int r = 0; r < size; r++) {
            if ((c == r) || ( c == size - r)) {
                myArr[r][c] = 'X';
            } else { 
                myArr[r][c] = ' ';
            }
        }
    }
    return myArr;
}
eumiro
This still only covers one diagonal- the easy one where the rows and columns numbers are equal. What about the right to left diagonal where the row and column numbers are not the same?
newtojava
Isn't ((c == r) || ( c == size - r)) covering both diagonals?
eumiro
A: 

You code seems a little bit overcomplicated with all those ifs and clever loops.
Just fill array with 'background chars' and then draw diagonal.

    char[][] myArr = new char[size][size];
    for (int i = 0; i < size; ++i) {
        Arrays.fill(myArr[i], ' ');
    }
    // now we have square filled with spaces

    // draw diagonal, like you did it
    for (int c = 0; c < size; c++) {
        myArr[c][c] = 'X';
        myArr[c][size - c - 1] = 'X';
    }

edit
Updated to draw two diagonals.

Nikita Rybak
I dont see what you did there..myArr[i]=new char[size]..what was that for? Also when you use Arrays.fill(myArr[i], ' '), how come you only specify one dimension and not two?
newtojava
@Nikita Rybak: The code you posted still only draws one diagonal (from NW corner to SE corner). You still need to draw a diagonal from NE to SW corners. Also, why initialize the array values with "background chars"? Besides adding overhead, I can't think of anything else it would do.
SauceMaster
@SauceMaster _The code you posted still only draws one diagonal (from NW corner to SE corner)_ I mentioned it and said why in my answer.
Nikita Rybak
I thought I was drawing two? Theres the first loop where the dimensions are the same [c][c], which is the left to right loop. Then there is the other nested loop which draws the right to left loop, no?
newtojava
@SauceMaster _Besides adding overhead_ Are you saying it's a waste of resources to make _N^2 + 2*N_ assignments instead of _N^2_? :) I just did what produces simpler code.
Nikita Rybak
@Nikita Rybak: I think I misinterpreted the role your code was intended to fill; i.e. obviate the step of adding the spaces (' '). Apologies for my careless once-over.
SauceMaster
@newtojava two-dimensional array in java is just array of arrays. No magic. So, if you have 'char[][] myArr', then 'myArr[0]' has type 'char[]'. And 'Arrays.fill' takes 'char[]'.
Nikita Rybak
@newtojava Your first loop draws perfectly correct diagonal. Nothing nested. So, why do we need nested loop to draw another diagonal? The fact that two loops (inner*outer) will draw _size^2_ (25 in your case) X's is already suspicious: diagonal has only _size_ (5) X's.
Nikita Rybak
@Nikita so if we take the first dimension to represent the rows in the square, are we just using the code you had to fill every row with spaces?
newtojava
@newtojava exactly, row by row. Or you could use inner loop with the same effect, something like _for(int col=0; col < size; ++col) {myArr[row][col] = 'X'}_. Sorry for confusion :)
Nikita Rybak
+1  A: 

When you Iterate your loop, you want the diagonals to be 'x'. You can save a lot of work and code by minimizing how much you iterate.

public static char[][] square(int z) {
int size = z;
char[][] myArr = new char[size][size];

for(int i = 0;i < size;i++)
{
    for(int j = 0;j < size;j++)
    {
        if(i == j)
        {
             myArr[i][j] = 'X';
        }
        else if(i + j == size - 1)
        {
             myArr[i][j] = 'X';
        else
        {
             myArr[i][j] = " ";
        }
     }
}

return myArr;

}
Bryan Harrington
This is only the right to left diagonal, what about the left to right diagonal, where i!=j?
newtojava
Also, your not even using the parameter 'z'. We could eliminate that as well. I'm not quite sure what your challenging us on, but I think that function just creates the array you described, if we want to be creative we could just use x as the dimensions of the square and have an x,x sized square with 'X' in the middle! =)
Bryan Harrington
I had it, but you still gota subtract i + j = size - 1;
Bryan Harrington
A: 

First problem is that when you do new char[size][size]; you still should new each char array before you use it.

This can be merged with the first for loop easily:

 for (int c=0;c<size;c++) {
    myArr[c] = new char[size]; // allocate the array
    myArr[c][c]='X';
 }

Next the algorithm doesn't work, though this one would:

public static char[][] square (int z) {
    int size = z, cap=((size+1) /2);
    char[][] myArr = new char[size][size];
    for (int c = 0; c < cap; c++) { // iterate only half the array doing 4 positions per iteration
        myArr[c] = new char[size];
        myArr[size-c-1] = new char[size];
        Arrays.fill(myArr[size-c-1],' '); // make the new line blank
        Arrays.fill(myArr[c], ' '); // make the new line blank
        myArr[c][c] = 'X';  // top left to center
        myArr[size - c - 1][size-c-1] = 'X'; // bottom right to center
        myArr[size - c - 1][c] = 'X'; // bottom left to center
        myArr[c][size - c - 1] = 'X'; // top right to center
    }
    return myArr;
}

/** test square algorithm by printing it to System.out */
private static void testSquare () {
    char[][] sq = square(5);
    for (char[] l : sq) {
        System.out.println(new String(l));
    }
}