簡體   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