views:

59

answers:

6

If I have a 2d array like:

boolean[][] map = new boolean[50][50];

How can I set the outer edge of booleans to true only in a loop?

So, for the following array:

0 0 0 0 0 0   
0 0 0 0 0 0   
0 0 0 0 0 0   
0 0 0 0 0 0 
0 0 0 0 0 0

You would have:

1 1 1 1 1 1
1 0 0 0 0 1 
1 0 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

I'm new to programming and I've been struggling to get this to work?

I thought possibly using 2 loops like:

for(int i = 0; i < map.length; i++)
{
    map[i][0] = true;
    map[i][map[0].length] = true;
}

for(int i = 0; i < map[0].length; i++)
{
    map[0][i] = true;
    map[map.length][i] = true;
}

But honestly I'm not sure if this is the correct approach?

+3  A: 
for( int i = 0; i<maxx; i++)
{
  for( int j = 0; j<maxy; j++)
  {
    if( i==0 || i == maxx-1 || j == 0 || j == maxy-1 )
    {
       //Write 1
    }
    else
    {
       //Write 0
    }
  }
}

This is probably not the best possible code, but it demonstrates easily how to achieve it:

Write something in all fields.
If the field is:

  1. At the top or bottom of the 2d array
  2. to the left or right

write a 1, otherwise a 0.

The question is, when it is at the top or bottom?
At the time the line-index (i) is either 0 or highest possible.
The same counts for the column index (j).

StampedeXV
This will consider every cell in the array, i wonder if there is a more efficient way to do this
CRice
as I wrote: there are more efficient ways. But the example should show very clearly the way you could go when tackling the problem (at least in my opinion).
StampedeXV
A: 

In Java:

int firstRow = 0;
int lastRow = map.length - 1;
int width = map[0].length;

for (int i=0; i<width; i++) {
    map[firstRow][i] = true;
}
System.arrayCopy (map[firstRow], 0, map[lastRow], 0, width);

int lastColumn = width - 1;
for (int i=1; i<lastRow; i++) {
    map[i][0] = map[i][lastColumn] = true;
}
Aaron Digulla
A: 

This is of course limited by the number of writes you must do, which are O(n) where n is the side length of the matrix, assuming the matrix is square.

You can of course simplify the code to only touch the outer elements:

for i in xrange(0, n - 1):
  matrix[0][i] = true
  matrix[i][-1] = true
  matrix[-1][-(i + 1)] = true
  matrix[-(i + 1)][0] = true

This does four writes per iteration of the loop. I think I did the indexing correctly now, the idea is to do the writes in this order, for the case where n=4 (apologies for the stunning ASCII graphics):

 0120
 2  1
 1  2
 0210

So, you can see that each side only goes from 0 to n - 2, inclusive. This is expressed in Python as for i in xrange(0, n -1).

unwind
If that is python you can just use [-1] instead of [n-1]
gnibbler
@gnibbler: Aarggh, true, I always forget. :)
unwind
+1  A: 
gnibbler
+1  A: 

I'm assuming the structure is already initialized with 0s.

integer max = 50;
boolean[][] map = new boolean[max][max];
for ( integer x=0;x<max;x++) {
   map[0,x] =1;
   map[max-1,x] =1;
   map[x,0] =1;
   map[max-1,x] =1;
}

Problem: this initializes the corners more than once ..

lexu
Personally I didn't think it was worth the bother to worry about doing the corners more than once, but if it concerns you, change your loop to start from x=1 and adapt the indices slightly as unwind did
gnibbler
I agree, it's not a problem .. but since the OP seems to be a beginner, I wanted to point it out explicitly. gnibbler coded around this .. but had to sacrifice some "readability"
lexu
A: 

In Python it is very easy


X=10
Y=5
m=[[1]*X]+[[1]+[0]*(X-2)+[1]]*(Y-2)+[[1]*X]
for row in m:
    print row

outputs:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Here is the breakdown

[1]*X       # gives us a list of X 1's [1,1,1,1,1,1,1,1,1,1] in this case

[0]*(X-2)   # gives us a list of (X-2) 0's [0,0,0,0,0,0,0,0] in this case

so

[[1]*x]     # gives us an 1 by X array [[1,1,1,1,1,1,1,1,1,1]]

[[1]+[0]*(X-2)+[1]]  # gives a 1 by X array [[1,0,0,0,0,0,0,0,0,1]]

we multiply the array above to give Y-2 identical lines

and then add another row of 1's to the bottom

gnibbler
`m=[[1]*X]+[[1]+[0]*(X-2)+[1]]*(Y-2)+[[1]*X]` - yes. Very easy. Very readable. :-)
Arve Systad