我想用1D数组表示2D数组。函数将传递两个索引(x,y)和要存储的值。这两个标记将代表一维数组的单个元素,并进行相应设置。我知道一维数组需要具有arrayWidth×arrayHeight的大小,但是我不知道如何设置每个元素。
例如,如何区分(2,4,3)与(4,2,3)?我尝试将数组设置为x * y,但是2 * 4和4 * 2会在数组中产生相同的斑点,我需要它们有所不同。
Answers:
您需要确定数组元素是以行顺序还是列顺序存储,然后保持一致。http://en.wikipedia.org/wiki/Row-major_order
C语言对多维数组使用行顺序
要使用一维数组进行模拟,请将行索引乘以宽度,然后按以下方式添加列索引:
int array[width * height];
int SetElement(int row, int col, int value)
{
array[width * row + col] = value;
}
alpha
,而2D数组N
在两个方向上都具有带有索引的维x, y
,则根据@JohnKnoeller ,alpha=x+N*y
。反过来的方法是设置x=alpha%N
和y= (alpha-alpha%N)/N
。
将2D数组索引重新计算为1D数组索引的典型公式为
index = indexX * arrayWidth + indexY;
或者,您可以使用
index = indexY * arrayHeight + indexX;
(假设arrayWidth
沿X轴和arrayHeight
Y轴测量)
当然,可以提供许多不同的公式来提供替代的唯一映射,但是通常不需要这样做。
在C / C ++语言中,内置多维数组存储在内存中,因此最后一个索引更改最快,这意味着对于声明为
int xy[10][10];
元素xy[5][3]
紧随其后xy[5][4]
在内存中。您可能还希望遵循该约定,根据您认为是两个索引中的“最后一个”的索引(X或Y)选择以上两个公式之一。
示例:我们要表示大小为SIZE_X和SIZE_Y的2D数组。这意味着我们将有MAXY个连续的MAXX大小的行。因此,设定函数为
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 ]; }
MAXX
和MAXY
值是容易混淆的名字命名,因为最大值x
和y
是MAXX - 1
和MAXY - 1
分别。也许SIZE_X
并且SIZE_Y
可能会更好?
正如其他人所说的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
重要的是,以可以使用所用语言检索的方式存储数据。C语言按行优先顺序存储(第一行的所有内容都在前,然后第二行的所有内容……),每个索引从0到其维度1。因此,数组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)查找X_C_language [i] [j]。例如,X_C_language [1] [2]等于X_FORTRAN(3,2)。在一维数组中,该数据值位于X1dim_C_language [2 * Cdim2 + 3],该位置与X1dim_FORTRAN(2 * Fdim1 + 3 +1)相同。请记住,Cdim2 = Fdim1是因为索引的顺序相反。
MATLAB与FORTRAN相同。除了索引通常从1开始,Ada与C相同。任何语言的索引都将以C或FORTRAN顺序之一开始,并且索引将从0或1开始,并且可以相应地进行调整以获取存储的数据。
抱歉,如果这种解释令人困惑,但我认为对于程序员而言,这是正确且重要的。
您应该能够使用简单的指针访问2d数组。数组[x] [y]将在指针中排列为p [0x *宽度+ 0y] [0x *宽度+ 1y] ... [0x *宽度+ n-1y] [1x *宽度+ 0y]等。