views:

910

answers:

6

I want to represent a 2D array with a 1D array. A function will pass the two indicies (x,y) and the value to store. These two indicies would represent a single element of a 1D array, and set it accordingly. I know the 1D array needs to be (arrayWidth *arrayHeight) in size, but I don't know how to set each element. For example if I passed it (2,4,3) how do i distinguish that from (4,2,3)? I tried setting the array as the x*y, but as you can see 2*4 and 4*2 would result in the same spot in the array, when i need them to be different. This might be unclear, if you need more information or clarification just ask. I hope you can help.

A: 

You should be able to access the 2d array with a simple pointer in place. The array[x][y] will be arranged in the pointer as p[0x * width + 0y][0x * width + 1y]...[0x * width + n-1y][1x * width + 0y] etc.

Arthur Kalliokoski
+6  A: 

Example : we want to represent an 2D array of SIZE_X and SIZE_Y size. That means that we will have MAXY consecutive rows of MAXY size. Hence the set function is

void set_array( int x, int y, int val ) { array[ x * SIZE_Y + y ] = val; }

The get would be:

int get_array( int x, int y ) { return array[ x * SIZE_Y + y ]; }
Kornel Kisielewicz
Your `MAXX` and `MAXY` values are confusingly named, because the maximum values of `x` and `y` are `MAXX - 1` and `MAXY - 1` respectively. Perhaps `SIZE_X` and `SIZE_Y` might be better?
caf
[y * maxx + x] is column order, not row order. This is the way matlab works, but isn't the way arrays normally work in C.
John Knoeller
@John valid point, @caf also
Kornel Kisielewicz
A: 

you can't really pass in (2,4,3) since you only have two params, ie x and y.

But the formula is x+y*arrayWidth.

mlathe
he can -- x, y, value :>
Kornel Kisielewicz
snap...........
mlathe
A: 

using row major example:

A(i,j) = a[i + j*ld]; // where ld is the leading dimension
                      // (commonly same as array dimension in i)

// matrix like notation using preprocessor hack, allows to hide indexing
#define A(i,j) A[(i) + (j)*ld]

double *A = ...;
size_t ld = ...;
A(i,j) = ...;
... = A(j,i);
aaa
+4  A: 

You need to decide whether the array elements will be stored in row order or column order and then be consistent about it. http://en.wikipedia.org/wiki/Row-major_order

The C language uses row order for Multidimensional arrays

To simulate this with a single dimensonal array, you multiply the row index by the width, and add the column index thus:

 int array[width * height];

 int SetElement(int row, int col, int value)
 {
    array[width * row + col] = value;  
 }
John Knoeller
I think this answer is more clearer, especially for beginners it's better not writing functions in one line...!! It's bad practice anyway.. :)
Lipis
+1  A: 

The typical formula for recalculation of 2D array indices into 1D array index is

index = indexX * arrayWidth + indexY;

Alternatively you can use

index = indexY * arrayHeight + indexX;

(assuming that arrayWidth is measured along X axis, and arrayHeight along Y axis)

Of course, one can come up with many different formulae that provide alternative unique mappings, but normally there's no need to.

In C/C++ languages built-in multidimensional arrays are stored in memory so that the last index changes the fastest, meaning that for an array declared as

int xy[10][10];

element xy[5][3] is immediately followed by xy[5][4] in memory. You might want to follow that convention as well, choosing one of the above two formulae depending on which index (X or Y) you consider to be the "last" of the two.

AndreyT