If you want to use the indexing that you used and you want to avoid the loop, you can invert the function for indexing. I will use k to denote a linear index, and all indices are zero based. As you noted
k = j + n * i - i * (i-1) / 2.
Seeing that we are working with positive integers here, and the fact that all combinations (i, j) are mapped to a separate k means that the function is invertible. The way I do this is, first of all, to note that
j = k - n * i + i * (i-1) / 2
so if you can find the row you are in, the column is determined by the equation above. Now consider that you need a string that is defined as
row = min {i | k - ni + i (i-1) / 2> = 0}.
If you solve the quadratic equation k - ni + i (i-1) / 2 = 0 and occupy the floor i, this gives you a line, i.e.
row = floor ((2n + 1 - sqrt ((2n + 1) ^ 2 - 8k)) / 2)
then
j = k - string * n + string * (string-1) / 2.
In pseudo code it will be
//Given linear index k, and n the size of nxn matrix i = floor( ( 2*n+1 - sqrt( (2n+1)*(2n+1) - 8*k ) ) / 2 ) ; j = k - n*i + i*(i-1)/2 ;
This eliminates the need for a loop and will be much faster for large matrices.
Keeran brabazon
source share