将2D阵列映射到1D阵列
我想用1D阵列表示2D阵列。函数将传递两个标记(x,y)和要存储的值。这两个标记将表示一维数组的单个元素,并对其进行相应设置。我知道1D数组需要具有arrayWidth×arrayHeight的大小,但我不知道如何设置每个元素。将2D阵列映射到1D阵列
例如,如何区分(2,4,3)和(4,2,3)?我尝试将数组设置为x * y,但2 * 4和4 * 2会导致数组中的相同点,我需要它们不同。
您需要确定数组元素是否将存储在行顺序或列顺序,然后保持一致。 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;
}
您应该可以通过简单的指针访问2d数组。数组[x] [y]将在指针中排列为p [0x * width + 0y] [0x * width + 1y] ... [0x * width + n-1y] [1x * width + 0y]等
示例:我们想要表示SIZE_X和SIZE_Y大小的二维数组。这意味着我们将有MAXY连续的MAXX大小的行。因此,集功能
void set_array(int x, int y, int val) { array[ x * SIZE_Y + y ] = val; }
的get是:使用行主要例如
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'可能会更好? – caf 2010-01-27 23:29:11
[y * maxx + x]是列顺序,而不是行顺序。这是matlab工作的方式,但不是数组通常在C中工作的方式。 – 2010-01-27 23:33:20
@John有效点,@caf也 – 2010-01-27 23:38: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);
用于2D阵列的索引的再计算成一维数组索引的典型配方是
index = indexX * arrayWidth + indexY;
或者您可以使用
index = indexY * arrayHeight + indexX;
(假设arrayWidth
沿X轴测量的,并且沿着Y轴arrayHeight
)
当然,可以想出的是提供替代的独特映射许多不同的公式,但通常没有必要对。
在C/C++语言内置的多维数组存储在存储器中,使得最后索引变化最快的,这意味着用于声明为
int xy[10][10];
元件xy[5][3]
在存储器之后紧接着xy[5][4]
阵列。您可能也想遵循该惯例,根据您认为哪个索引(X或Y)是两者中的“最后”选择上述两个公式中的一个。
以能够以所用语言检索数据的方式存储数据很重要。 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]与1维数组条目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)。在1维数组中,该数据值位于与X1dim_FORTRAN(2 * Fdim1 + 3 + 1)相同位置的X1dim_C_language [2 * Cdim2 + 3]。请记住Cdim2 = Fdim1,因为索引的顺序是相反的。
MATLAB与FORTRAN相同。除了索引通常从1开始,Ada与C相同。任何语言的索引都在C或FORTRAN命令之一中,索引将从0或1开始,并可以相应地进行调整以获取存储的数据。
对不起,如果这个解释令人困惑,但我认为它是准确和重要的程序员知道。
行顺序当其他都该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
我认为这个答案更清晰,特别是对于初学者来说,最好不要将函数写入一行...... !!这是不好的做法无论如何.. :) – Lipis 2010-01-27 23:38:36
这个答案也是有用的,当你有一个编译器(如嵌入式系统),没有适当的multidimensio nal array support – 2013-12-06 21:50:37
令人惊讶的是,有多少人可以正确回答相同的问题,但只有其中一人以易于理解的方式表示。 这就像答案一样简单。然而,约翰是唯一真正为其提供良好答案的人。其余的垃圾只能被那些已经知道答案的人容易理解。感谢约翰,实际上用英语而不是外星人来说。 只是表明一些人在教学方面有多糟糕,以及John Knoeller这样的老师如何比其他人更有效地简化和沟通。 – user2948630 2014-02-15 02:03:53