tags:

views:

340

answers:

6

This might be stupid, but I'm want to know if it's possible, lets start with 5x5 a matrix

int[][] x = new int[5][5];   
Random rg = new Random();

now let's fill it with Pseudo Random information

for(int i=0;i<5;i++){
    for(int j =0; j<5;j++){
        x[i][j] = rg.nextInt(); 
    }   
}

but how can I do this right with one Single for?

for(int i=0, j=0; i<5; (j==5?i++, j=0:j++){
    x[i][j] = rg.nextInt();
}

this is not working :(

+19  A: 

You need to compute the row and column from a single index, then:

for(int i = 0; i < 5 * 5; i++)
{
   int row = i / 5;
   int column = i % 5;
   x[row][column] = rg.nextInt();
}

The use of / and % is classic, here: as you iterate over the indices of the matrix, the division is used to figure out which row you're on. The remainder (%) is then the column.

This gorgeous ASCII art shows how the 1-dimensional indices are located in the 2D matrix:

 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

It should be clear that for any value in the first row, that value divided by 5 is the row index itself, i.e. they're all 0.

unwind
However, I don't think it will be quicker than the 2-for imbricated version, it's still O(n²) complexity.
Valentin Rocher
@Bishiboosh: No, I don't think it's quicker either ... Never said it would be, just wanted to show how to do it using a single loop, like the original question asked.
unwind
+1 for gorgeous ascii art
willcodejavaforfood
sometimes, in C, pointer arithmetics is faster than array de-referencing, hence this *might* be useful. But that is moot since premature optimization is the root of all bugs =)
Chii
If you want it to go faster, move to a single array. Chii: There are pretty good optimising compilers these days (although removing bounds checking is tricky).
Tom Hawtin - tackline
Another +1 for gorgeous ASCII art! :)
Bombe
A: 

int q = 5, r= 5; int [][] x = new int [q][r]

for(int i = 0, i < q * r, i++)
{
    int xaxis = i / q;
    int yaxis = i % r;

    x[xaxis][yaxis] = rg.nextInt();
}

Though I don't know why you'd want to... you still have the same number of iterations and this is IMHO more difficult to read and requires more mathematical calculations to run, so it's probably slower if you profile it

Eoin Campbell
this doesn't work: (1) for uses ';' as separator, not ',' (2) it only works for q == r; if q<r you'll get an ArrayIndexOutOfBoundsException, if q>r not all elements will be set. It should be "int xaxis = i / r;"
Carlos Heuberger
+2  A: 

Another way to do it would be:

int i,j;
for (i=0,j=0; i<5 && j<5; i = (i==4 ? 0 : i+1), j = (i==4 ? j+1 : j))
{
   x[i][j] = rg.nextInt();
}

Although, I prefer unwind's solution.

Pablo Santa Cruz
more like the example i tried, thx
Midday
+8  A: 

You really will not gain anything from doing that. keep your code readable. it's actually more intensive to do the multiplications and divisions unwind suggested then to just to a loop. (multiply divide and mod are actually a complex set of instructions in an ALU)

Bluephlame
A: 

I got curious and did a benchmark.

For Suns HotSpot 64 server jvm on Linux, both nested loops and unwrapped loops were more or less equally fast, and almost as fast as iterating over a linear array of [size*size]. The unwrapped loop where infact slowe than the nested loop, probably because it does some more math.

However, On IBMs jdk 1.5 32 bit on Windows, the nested loop is more than 10x slower.

Though, I am not sure if its the compiler or the jvm that matters in this case, the slower test was compiled using IBMs RAD wich is some year older than eclipse 3.4

So the only reason to mess up your code with these optimizations would be if you are stuck on an "enterprisy" platform with an old jvm and and compiler, and it's really really time critical.

KarlP
A: 

the nested loops will be extremely fast once the hotspot compiler runs them a few times.. see this excellent article for an explanation.

Andreas Petersson