82 votes

Mettre en correspondance un tableau 2D avec un tableau 1D C

Je veux représenter un tableau 2D avec un tableau 1D. Une fonction passera les deux indicateurs (x,y) et la valeur à stocker. Ces deux indicateurs représentent un seul élément d'un tableau 1D, et le définissent en conséquence. Je sais que le tableau 1D doit avoir une taille de (arrayWidth *arrayHeight), mais je ne sais pas comment définir chaque élément. Par exemple, si je lui passe (2,4,3), comment puis-je le distinguer de (4,2,3) ? J'ai essayé de définir le tableau comme x*y, mais comme vous pouvez le voir, 2*4 et 4*2 se retrouveraient au même endroit dans le tableau, alors que j'ai besoin qu'ils soient différents. Ceci n'est peut-être pas clair, si vous avez besoin de plus d'informations ou de précisions, n'hésitez pas à demander. J'espère que vous pourrez m'aider.

148voto

John Knoeller Points 20754

Vous devez décider si les éléments du tableau seront stockés dans l'ordre des lignes ou des colonnes et être cohérent à ce sujet. http://en.wikipedia.org/wiki/Row-major_order

Le langage C utilise l'ordre des lignes pour les tableaux multidimensionnels.

Pour simuler cela avec un tableau à une seule dimension, vous multipliez l'indice de la ligne par la largeur, et ajoutez ainsi l'indice de la colonne :

 int array[width * height];

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

17voto

AndreyT Points 139512

La formule type pour le recalcul des indices de tableaux 2D en indices de tableaux 1D est la suivante

index = indexX * arrayWidth + indexY;

Vous pouvez également utiliser

index = indexY * arrayHeight + indexX;

(en supposant que arrayWidth est mesurée le long de l'axe X, et arrayHeight le long de l'axe Y)

Bien sûr, on peut trouver de nombreuses formules différentes qui fournissent des correspondances uniques alternatives, mais normalement, ce n'est pas nécessaire.

Dans les langages C/C++, les tableaux multidimensionnels intégrés sont stockés en mémoire de manière à ce que le dernier indice change le plus rapidement, ce qui signifie que pour un tableau déclaré comme étant

int xy[10][10];

élément xy[5][3] est immédiatement suivi par xy[5][4] en mémoire. Vous pouvez également suivre cette convention, en choisissant l'une des deux formules ci-dessus en fonction de l'indice (X ou Y) que vous considérez comme le "dernier" des deux.

15voto

Kornel Kisielewicz Points 26556

Exemple : nous voulons représenter un tableau 2D de taille SIZE_X et SIZE_Y. Cela signifie que nous aurons MAXY lignes consécutives de taille MAXY. Par conséquent, la fonction d'ensemble est

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

L'obtenir serait :

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

1voto

Anycorn Points 20521

À l'aide d'un exemple majeur de rang :

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

1voto

Mark Points 11

Il est important de stocker les données de manière à ce qu'elles puissent être récupérées dans les langues utilisées. Le langage C stocke dans l'ordre rangée-major (toute la première rangée vient en premier, puis toute la deuxième,...) avec chaque index allant de 0 à sa dimension-1. Donc l'ordre du tableau x[2][3] est x[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2]. Ainsi, en langage C, x[i][j] est stocké au même endroit qu'une entrée de tableau à 1 dimension x1dim[ i*3 +j]. Si les données sont stockées de cette manière, il est facile de les récupérer en langage C.

Fortran et MATLAB sont différents. Ils stockent dans l'ordre colonne-majeur (toute la première colonne vient en premier, puis toute la deuxième ligne, ...) et chaque index va de 1 à sa dimension. L'ordre des index est donc l'inverse de celui de C et tous les index sont supérieurs de 1. Si vous stockez les données dans l'ordre du langage C, FORTRAN peut trouver X_C_language[i][j] en utilisant X_FORTRAN(j+1, i+1). Par exemple, X_C_language[1][2] est égal à X_FORTRAN(3,2). Dans les tableaux unidimensionnels, cette valeur de données se trouve à X1dim_C_language[2*Cdim2 + 3], qui est la même position que X1dim_FORTRAN(2*Fdim1 + 3 + 1). N'oubliez pas que Cdim2 = Fdim1 car l'ordre des indices est inversé.

MATLAB est identique à FORTRAN. Ada est identique au C, sauf que les indices commencent normalement à 1. Dans n'importe quel langage, les indices seront dans l'un de ces ordres C ou FORTRAN et les indices commenceront à 0 ou 1 et pourront être ajustés en conséquence pour obtenir les données stockées.

Désolé si cette explication est confuse, mais je pense qu'elle est précise et importante à connaître pour un programmeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X