将二维数组映射到一维数组上

我想用一维数组来表示二维数组。 函数将传递两个指示(x,y)和要存储的值。 这两个标记将表示一维数组的单个元素,并相应地进行设置。 我知道一维数组需要有arrayWidth×arrayHeight的大小,但我不知道如何设置每个元素。

例如,我如何区分(2,4,3)和(4,2,3)? 我试着将数组设置为x * y,但是2 * 4和4 * 2会导致数组中的相同点,我需要它们不同。

您需要确定数组元素是按行顺序还是按列顺序存储,然后保持一致。 http://en.wikipedia.org/wiki/Row-major_order

C语言使用multidimensional array的行顺序

要用单维数组来模拟这个,可以将行索引乘以宽度,然后添加列索引:

int array[width * height]; int SetElement(int row, int col, int value) { array[width * row + col] = value; } 

例如:我们想要表示一个SIZE_X和SIZE_Y大小的二维数组。 这意味着我们将有MAXY连续的MAXX大小的行。 因此设定的function是

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

得到的将是:

 int get_array( int x, int y ) { return array[ x * SIZE_Y + y ]; } 

二维数组索引重新计算为一维数组索引的典型公式为:

 index = indexX * arrayWidth + indexY; 

或者你可以使用

 index = indexY * arrayHeight + indexX; 

(假设arrayWidth是沿X轴测量的, arrayWidth是沿着Y轴的)

当然,可以提出许多不同的公式来提供可选的独特映射,但通常不需要。

在C / C ++语言中,内置的multidimensional array存储在内存中,这样最后一个索引变化最快,这意味着对于声明为

 int xy[10][10]; 

元素xy[5][3] xy[5][4]在内存中紧跟着xy[5][4] 。 您可能也想遵循该惯例,根据您认为哪个索引(X或Y)是两者中的“最后”来select上述两个公式中的一个。

正如其他人所说的C地图行顺序

  #include <stdio.h> int main(int argc, char **argv) { int i, j, k; int arr[5][3]; int *arr2 = (int*)arr; for (k=0; k<15; k++) { arr2[k] = k; printf("arr[%d] = %2d\n", k, arr2[k]); } for (i=0; i<5; i++) { for (j=0; j< 3; j++) { printf("arr2[%d][%d] = %2d\n", i, j ,arr[i][j]); } } } 

输出:

 arr[0] = 0 arr[1] = 1 arr[2] = 2 arr[3] = 3 arr[4] = 4 arr[5] = 5 arr[6] = 6 arr[7] = 7 arr[8] = 8 arr[9] = 9 arr[10] = 10 arr[11] = 11 arr[12] = 12 arr[13] = 13 arr[14] = 14 arr2[0][0] = 0 arr2[0][1] = 1 arr2[0][2] = 2 arr2[1][0] = 3 arr2[1][1] = 4 arr2[1][2] = 5 arr2[2][0] = 6 arr2[2][1] = 7 arr2[2][2] = 8 arr2[3][0] = 9 arr2[3][1] = 10 arr2[3][2] = 11 arr2[4][0] = 12 arr2[4][1] = 13 arr2[4][2] = 14 

使用行主要示例:

 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); 

存储数据的方式非常重要,可以使用所用的语言进行检索。 C语言存储按行优先顺序排列(所有的第一行先到第二行,然后是所有的第二行,…),每个索引从0到它的第一个维度。 因此,数组x [2] [3]的顺序是x [0] [0],x [0] [1],x [0] [2],x [1] [0],x [1] [ 1],x [1] [2]。 所以在C语言中,x [i] [j]被存储在与一维数组项x1dim [i * 3 + j]相同的地方。 如果以这种方式存储数据,则很容易用C语言进行检索。

Fortran和MATLAB是不同的。 它们以列主要的顺序存储(所有的第一列先到第二行,然后是所有的第二行),每个索引从1到它的维度。 因此,指数顺序与C相反,所有指数都大于1。 如果以C语言顺序存储数据,则FORTRAN可以使用X_FORTRAN(j + 1,i + 1)findX_C_language [i] [j]。 例如,X_C_language [1] [2]等于X_FORTRAN(3,2)。 在1维数组中,该数据值位于与X1dim_FORTRAN(2 * Fdim1 + 3 + 1)相同位置的X1dim_C_language [2 * Cdim2 + 3]。 请记住Cdim2 = Fdim1,因为索引的顺序是相反的。

MATLAB和FORTRAN是一样的。 除了索引通常从1开始,Ada与C相同。任何语言都将具有C或FORTRAN命令之一的索引,并且索引将从0或1开始,并且可以相应地调整以获得存储的数据。

对不起,如果这个解释是混乱的,但我认为这是准确的和重要的程序员知道。

你应该可以用一个简单的指针访问2d数组。 数组[x] [y]将在指针中排列为p [0x * width + 0y] [0x * width + 1y] … [0x * width + n-1y] [1x * width + 0y]等。