Pourquoi avons-nous à la fois un tableau dentelé et un tableau multidimensionnel?

87
  1. Quelle est la différence entre un tableau dentelé et un tableau multidimensionnel. Y a-t-il un avantage de l'un sur l'autre?

  2. Et pourquoi Visual Studio ne me permettrait-il pas de faire un

    MyClass[][] abc = new MyClass[10][20];
    

    (Nous avions l'habitude de faire cela en C ++, mais en C #, cela souligne [20] avec une ligne rouge ondulée .. Dit un spécificateur de rang non valide)

    mais est content de

    MyClass[,] abc = new MyClass[10,20];
    
  3. Enfin comment puis-je initialiser cela en une seule ligne (comme nous le faisons dans un tableau simple avec {new xxx...}{new xxx....})

    MyClass[][,][,] itemscollection;
    
Shekhar_Pro
la source
11
L'intérêt d'un tableau dentelé est que les tableaux "imbriqués" n'ont pas besoin d'être de taille uniforme.
Ani
1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - La syntaxe des tableaux multidimensionnels comme [X, Y] est valide selon la documentation
ndtreviv
Sous-question supplémentaire: est-il possible d'utiliser foreach () avec un tableau multidimensionnel?
Serge Wautier
@Serge - bien sûr, comme des Arrayoutils IEnumerable. Vous pouvez toujours l'essayer et voir par vous-même :)
thecoop

Réponses:

101
  1. Un tableau en dents de scie est un tableau de tableaux, donc an int[][]est un tableau de int[], dont chacun peut être de différentes longueurs et occuper son propre bloc en mémoire. Un tableau multidimensionnel ( int[,]) est un seul bloc de mémoire (essentiellement une matrice).

  2. Vous ne pouvez pas créer un MyClass[10][20]car chaque sous-tableau doit être initialisé séparément, car ce sont des objets séparés:

    MyClass[][] abc = new MyClass[10][];
    
    for (int i=0; i<abc.Length; i++) {
        abc[i] = new MyClass[20];
    }
    

    A MyClass[10,20]est ok, car il initialise un seul objet en tant que matrice avec 10 lignes et 20 colonnes.

  3. A MyClass[][,][,]peut être initialisé comme ceci (pas de test de compilation cependant):

    MyClass[][,][,] abc = new MyClass[10][,][,];
    
    for (int i=0; i<abc.Length; i++) {
        abc[i] = new MyClass[20,30][,];
    
        for (int j=0; j<abc[i].GetLength(0); j++) {
            for (int k=0; k<abc[i].GetLength(1); k++) {
                abc[i][j,k] = new MyClass[40,50];
            }
        }
    }
    

Gardez à l'esprit que le CLR est fortement optimisé pour l'accès aux tableaux à une seule dimension, donc l'utilisation d'un tableau dentelé sera probablement plus rapide qu'un tableau multidimensionnel de la même taille.

thecoop
la source
6
pouvez-vous nous montrer des preuves que les accès aux tableaux unidimensionnels sont plus rapides?
GreyCloud
Existe-t-il un cas d'utilisation (courant) pour le tableau multidimensionnel?
ryanwebjackson
1
Exemples: damier var board = new Piece[8, 8];, matrice de transformation var m = new double[2, 2]; .
Olivier Jacot-Descombes
37

Un tableau irrégulier est un tableau de tableaux. Il n'est pas garanti que chaque baie est de la même taille. Tu aurais pu

int[][] jaggedArray = new int[5][];
jaggedArray[0] = new[] {1, 2, 3}; // 3 item array
jaggedArray[1] = new int[10];     // 10 item array
// etc.

C'est un ensemble de tableaux associés.

Un tableau multidimensionnel, en revanche, est plus un groupement cohésif, comme une boîte, une table, un cube, etc., où il n'y a pas de longueurs irrégulières. C'est-à-dire

int i = array[1,10];
int j = array[2,10]; // 10 will be available at 2 if available at 1
Anthony Pegram
la source
J'ai essayé votre code. Il n'a pas compilé. Essayez d'ajouter int [3] alors essayez jaggedArray[0] = int[3]{ 1, 2, 3 };
barlop le
Je sais que c'est vieux, mais juste à des fins d'information, int [3] n'est pas nécessaire. un simple int [] est tout ce qui compte. int [] [] myArray = new int [5] []; myArray [0] = new int [] {1, 2, 3, 4}; C'est tout ce qui est nécessaire.
Velocibadgery
Pouvez-vous obtenir cela pour compiler en C #? Je ne peux pas compiler à jaggedArray[0] = { 1, 2, 3 };moins de le changer en = new[] { 1, 2, 3 }(ou = new int[] { 1, 2, 3 }avant C # 3.0). Selon le Guide de programmation C # de Microsoft , "Vous pouvez déclarer une variable de tableau sans la créer, mais vous devez utiliser l'opérateur new lorsque vous affectez un nouveau tableau à cette variable."
Joel V.Earnest-DeYoung
11

Un tableau rectangulaire a toujours le même nombre de colonnes pour chaque ligne.

MyClass[,] x = new MyClass[10,30]

Chaque ligne a 30 colonnes, alors que dans un tableau en dents de scie, ce n'est pas obligatoire. Par conséquent, je pense que vous devrez initialiser chaque `` ligne '' dans un tableau dentelé séparément:

MyClass[][] x = new MyClass[10][];

for(int i = 0; i < 10; i++)
{
    x[i] = new MyClass[30];
}

En fait, cela signifie que toutes les lignes du tableau dentelé ne doivent pas contenir le même nombre d'éléments. (Dans mon exemple, il a le même nombre d'éléments, mais ce n'est pas obligatoire).

Vous pouvez parfaitement le faire, par exemple:

MyClass[][] x = new MyClass[10][];

for(int i = 0; i < 10; i++)
{
    x[i] = new MyClass[(30 + i)];
}

Cela pourrait être un article intéressant pour vous.

Frederik Gheysels
la source
5

Ad 3) Pour initialiser un tel monstre comme [][,][,], vous pouvez faire quelque chose comme:

        int [,][,] multiArr1 = { { new int[,] { { 2, 2 }, { 1, 1 } },
                                     new int[,] { { 2, 2 }, { 1, 1 } } },
                                     { new int[,] { { 2, 2 }, { 1, 1 } },
                                         new int[,] { { 2, 2 }, { 1, 1 } } } };
        int [,][,] multiArr2 = { { new int[,] { { 2, 2 }, { 1, 1 } },
                                     new int[,] { { 2, 2 }, { 1, 1 } } },
                                     { new int[,] { { 2, 2 }, { 1, 1 } },
                                         new int[,] { { 2, 2 }, { 1, 1 } } } };

        int [][,][,] superMultiArray = { multiArr1, multiArr2 };
nan
la source
1

Si vous recherchez un tableau multidimensionnel avec des limites définies, utilisez toujours la [,]syntaxe de style. Cela garantira que chaque portion est de taille égale.

Lorsque vous utilisez [][]ce qui se passe réellement, vous créez un tableau de tableaux. Cela signifie alors que chaque tableau peut être dimensionné différemment. Par exemple:

int[][] jaggedArray = new int[5][]
for(int index = 0; index < jaggedArray.Length ; ++index)
{
    jaggedArray[index] = new int[index + 1];
}
Joshua Rodgers
la source
1

La déclaration en ligne ressemblerait à ceci:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
Josiah Ruddell
la source
1

Pour le n ° 1, voir cette question SO

Pour les tableaux en ligne dentelés ou multidimensionnels, consultez ce guide de programmation :

// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };

// Same array with dimensions specified at declaration.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };

Vous n'avez pas besoin de spécifier les dimensions (array3D), mais si vous savez qu'elles ne changeront jamais, il est utile de savoir quelles dimensions vous utilisez (array3Da).

rownage
la source
0

Vous devez comprendre le fonctionnement interne du tableau. Le tableau multidimensionnel agit comme un tableau à une seule dimension, sauf que la double indexation est convertie en une seule.

Votre tableau Jagged en c # est un tableau d'objets qui sont tour à tour des tableaux.

dvhh
la source
0

Je pense que l'allocation de mémoire de tableaux dentelés 2d en C # est comme les tableaux 2d en C ++ et C. Parce que les tableaux dentelés 2d ont un pointeur qui pointe vers un tableau de pointeurs que chacun de ces pointeurs pointe vers un tableau d'éléments (par exemple des éléments entiers); comme ce code en C ++,

int** 2DArr {new int* [number1]};
for (int i = 0; i < number1; i++)
{
   2DArr[i] = new int[number2];
}

l'allocation de mémoire du code ci-dessous est la même que celle des tableaux dentelés 2D en C #. Mais je doute, pourriez-vous s'il vous plaît expliquer plus si je pense mal.

ARSD
la source
0

Ce post est vieux mais voici mes réflexions à ce sujet.

Les tableaux dentelés sont des tableaux multidimensionnels. Les tableaux multidimensionnels sont disponibles en deux variétés: rectangulaires et dentelées. Les tableaux rectangulaires représentent un bloc de mémoire à n dimensions, et les tableaux dentelés sont des tableaux de tableaux.

Tableaux rectangulaires

Les tableaux rectangulaires sont déclarés en utilisant des virgules pour séparer chaque dimension. L'instruction suivante déclare un tableau rectangulaire à deux dimensions, dont les dimensions sont 3 × 3:

int[,] matrix = new int [3, 3]; 

Tableaux dentelés

Les tableaux dentelés sont déclarés en utilisant des crochets successifs pour représenter chaque dimension. Voici un exemple de déclaration d'un tableau bidimensionnel dentelé, où la dimension la plus externe est 3:

int[][] matrix = new int[3][];
Imir Hoxha
la source
0

Pour un tableau multidimensionnel, pensez à une boîte ou un rectangle. Chaque ligne a la même longueur et chaque colonne a la même longueur.

Dans un tableau irrégulier, les lignes et les colonnes peuvent ne pas avoir la même taille. Par exemple, les colonnes ou les lignes peuvent être de tailles différentes. Cela conduirait à une forme qui pourrait ne pas être une ligne droite sur les côtés comme un rectangle. Au lieu de cela, les côtés peuvent être déchiquetés .

Maintenant, j'ai utilisé 2 dimensions / 2 tableaux pour cet exemple, mais cela s'applique à plus.

Roblem
la source