繁体   English   中英

将2D阵列映射到1D阵列上

[英]Map a 2D array onto a 1D array

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

例如,我如何区分(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;  
 }

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

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 ]; }

正如其他人所说的那样,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]与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)。 在一维数组中,该数据值位于X1dim_C_language [2 * Cdim2 + 3],这与X1dim_FORTRAN(2 * Fdim1 + 3 + 1)的位置相同。 请记住,Cdim2 = Fdim1,因为索引的顺序是相反的。

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

很抱歉,如果这个解释令人困惑,但我认为这对程序员来说是准确而且重要的。

使用行主要示例:

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数组。 数组[x] [y]将在指针中排列为p [0x * width + 0y] [0x * width + 1y] ... [0x * width + n-1y] [1x * width + 0y]等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM