web-dev-qa-db-fra.com

Comment mapper les index d'une matrice sur un tableau unidimensionnel (C ++)?

J'ai une matrice 8x8, comme ceci:

char matrix[8][8];

De plus, j'ai un tableau de 64 éléments, comme celui-ci:

char array[64];

Ensuite, j'ai dessiné la matrice sous forme de tableau et rempli les cellules avec des nombres, chaque nombre étant incrémenté de gauche à droite, de haut en bas.

Si j'ai, disons, les index 3 (colonne) et 4 (ligne) dans la matrice, je sais que cela correspond à l'élément à la position 35 dans le tableau, comme on peut le voir dans le tableau que j'ai tracé. Je crois qu'il existe une sorte de formule pour traduire les 2 index de la matrice en un seul index du tableau, mais je ne peux pas comprendre ce que c'est.

Des idées?

39

La plupart des langues stockent les tableaux multidimensionnels en effectuant une conversion comme celle-ci:

Si matrix a une taille, n par m [c'est-à-dire i passe de 0 à (n-1) et j de 0 à (m-1)], puis:

matrix[ i ][ j ] = array[ i*m + j ].

Donc, c'est comme un système de nombres de base 'n'. Notez que la taille de la dernière dimension n'a pas d'importance.


Pour une compréhension conceptuelle, pensez à une matrice (3x5) avec "i" comme numéro de ligne et "j" comme numéro de colonne. Si vous commencez la numérotation à partir de i,j = (0,0) --> 0. Pour la commande 'row-major' (comme ceci), la disposition ressemble à:

           |-------- 5 ---------|
  Row      ______________________   _ _
   0      |0    1    2    3    4 |   |
   1      |5    6    7    8    9 |   3
   2      |10   11   12   13   14|  _|_
          |______________________|
Column     0    1    2    3    4 

Lorsque vous vous déplacez le long de la ligne (c.-à-d. Augmentez le nombre de colonnes), vous commencez simplement à compter, de sorte que les indices de tableau sont 0,1,2.... Lorsque vous arrivez à la deuxième ligne, vous avez déjà 5 Entrées, vous commencez donc avec des indices 1*5 + 0,1,2.... Sur la troisième ligne, vous avez déjà 2*5 Entrées, donc les indices sont 2*5 + 0,1,2....

Pour une dimension supérieure, cette idée se généralise, c'est-à-dire pour une 3D matrix L par N par M:

matrix[ i ][ j ][ k ] = array[ i*(N*M) + j*M + k ]

etc.


Pour une très bonne explication, voir: http://www.cplusplus.com/doc/tutorial/arrays/ ; ou pour certains aspects plus techniques: http://en.wikipedia.org/wiki/Row-major_order

80
DilithiumMatrix

Pour les commandes par ligne principale, je pense que la déclaration matrix[ i ][ j ] = array[ i*n + j ] Est erronée.

Le décalage doit être offset = (row * NUMCOLS) + column.

Votre relevé a pour résultat row * NUMROWS + column, Ce qui est faux.

Les liens que vous avez fournis donnent une explication correcte.

11
mvelusce

Quelque chose comme ça?

//columns = amount of columns, x = column, y = row
var calculateIndex = function(columns, x, y){
    return y * columns + x;
};

L'exemple ci-dessous reconvertit un index en coordonnées x et y.

//i = index, x = amount of columns, y = amount of rows
var calculateCoordinates = function(index, columns, rows){
    //for each row
    for(var i=0; i<rows; i++){
        //check if the index parameter is in the row
        if(index < (columns * i) + columns && index >= columns * i){
            //return x, y
            return [index - columns * i, i];
        }
    }
    return null;
};
5
Donny Verduijn