Warum haben wir sowohl ein gezacktes Array als auch ein mehrdimensionales Array?

85
  1. Was ist der Unterschied zwischen einem gezackten Array und einem mehrdimensionalen Array? Gibt es einen Vorteil von einem zum anderen?

  2. Und warum sollte mir das Visual Studio nicht erlauben, a

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

    (Früher haben wir das in C ++ gemacht, aber in C # wird [20] mit einer roten, zappeligen Linie unterstrichen. Sagt einen ungültigen Rangbezeichner.)

    ist aber zufrieden mit

    MyClass[,] abc = new MyClass[10,20];
  3. Schließlich, wie kann ich dies in einer einzelnen Zeile initialisieren (wie wir es in einfachen Arrays mit tun {new xxx...}{new xxx....})

    MyClass[][,][,] itemscollection;
Shekhar_Pro
quelle
11
Der springende Punkt eines gezackten Arrays ist, dass die "verschachtelten" Arrays keine einheitliche Größe haben müssen.
Ani
1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - Mehrdimensionale Array-Syntax als [X, Y] ist gemäß docs gültig
ndtreviv
Zusätzliche Unterfrage: Ist es möglich, foreach () mit mehrdimensionalem Array zu verwenden?
Serge Wautier
@ Serge - natürlich als ArrayGerät IEnumerable. Sie können es immer versuchen und selbst sehen :)
Thecoop

Antworten:

96
  1. Ein gezacktes Array ist ein Array von Arrays, also ein int[][]Array von Arrays int[], von denen jedes unterschiedlich lang sein kann und einen eigenen Block im Speicher belegt. Ein mehrdimensionales Array ( int[,]) ist ein einzelner Speicherblock (im Wesentlichen eine Matrix).

  2. Sie können keine erstellen, MyClass[10][20]da jedes Subarray separat initialisiert werden muss, da es sich um separate Objekte handelt:

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

    A MyClass[10,20]ist in Ordnung, da ein einzelnes Objekt als Matrix mit 10 Zeilen und 20 Spalten initialisiert wird.

  3. A MyClass[][,][,]kann wie folgt initialisiert werden (allerdings nicht kompiliert getestet):

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

Beachten Sie, dass die CLR stark für den Zugriff auf eindimensionale Arrays optimiert ist, sodass die Verwendung eines gezackten Arrays wahrscheinlich schneller ist als die Verwendung eines mehrdimensionalen Arrays derselben Größe.

thecoop
quelle
6
Können Sie uns Hinweise darauf geben, dass eindimensionale Array-Zugriffe schneller sind?
GreyCloud
Gibt es einen (allgemeinen) Anwendungsfall für das mehrdimensionale Array?
Ryanwebjackson
1
Beispiele: Schachbrett var board = new Piece[8, 8];, eine Transformationsmatrix var m = new double[2, 2]; .
Olivier Jacot-Descombes
36

Ein gezacktes Array ist ein Array von Arrays. Es ist nicht garantiert, dass jedes Array dieselbe Größe hat. Du könntest haben

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

Es ist eine Reihe verwandter Arrays.

Ein mehrdimensionales Array ist dagegen eher eine zusammenhängende Gruppierung wie eine Box, ein Tisch, ein Würfel usw., bei der es keine unregelmäßigen Längen gibt. Das heißt

int i = array[1,10];
int j = array[2,10]; // 10 will be available at 2 if available at 1
Anthony Pegram
quelle
Ich habe deinen Code ausprobiert. Es wurde nicht kompiliert. Versuchen Sie, int [3] hinzuzufügen, also versuchen Sie es jaggedArray[0] = int[3]{ 1, 2, 3 };
Barlop
Ich weiß, dass dies alt ist, aber nur zu Informationszwecken ist int [3] nicht notwendig. Ein einfaches int [] ist alles was zählt. int [] [] myArray = new int [5] []; myArray [0] = new int [] {1, 2, 3, 4}; Das ist alles was nötig ist.
Velocibadgery
Können Sie dies in C # kompilieren lassen? Ich kann nur kompilieren, jaggedArray[0] = { 1, 2, 3 };wenn ich es in = new[] { 1, 2, 3 }(oder = new int[] { 1, 2, 3 }vor C # 3.0) ändere . Im C # -Programmierhandbuch von Microsoft heißt es: "Sie können eine Array-Variable deklarieren, ohne sie zu erstellen. Sie müssen jedoch den neuen Operator verwenden, wenn Sie dieser Variablen ein neues Array zuweisen."
Joel V. Earnest-DeYoung
10

Ein rechteckiges Array hat immer die gleiche Anzahl von Spalten für jede Zeile.

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

Jede Zeile hat 30 Spalten, während dies in einem gezackten Array nicht erforderlich ist. Daher denke ich, dass Sie jede 'Zeile' in einem gezackten Array separat initialisieren müssen:

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

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

Tatsächlich bedeutet dies, dass nicht jede Zeile im gezackten Array die gleiche Anzahl von Elementen enthalten muss. (In meinem Beispiel hat es die gleiche Anzahl von Elementen, aber dies ist nicht erforderlich).

Sie können dies perfekt tun, zum Beispiel:

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

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

Dies könnte ein interessanter Artikel für Sie sein.

Frederik Gheysels
quelle
4

Anzeige 3) Um ein solches Monster wie zu initialisieren [][,][,], können Sie Folgendes tun:

        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
quelle
1

Wenn Sie nach einem mehrdimensionalen Array suchen, für das Grenzen festgelegt wurden, verwenden Sie immer die [,]Stilsyntax. Dadurch wird sichergestellt, dass jede Portion gleich groß ist.

Wenn Sie verwenden, [][]ist es wirklich so, dass Sie ein Array von Arrays erstellen. Dies bedeutet dann, dass jedes Array unterschiedlich dimensioniert werden kann. Beispielsweise:

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

Die Inline-Deklaration würde ungefähr so ​​aussehen:

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

Für # 1 siehe diese SO-Frage

Informationen zu gezackten oder mehrdimensionalen Inline-Arrays finden Sie in dieser Programmieranleitung :

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

Sie müssen die Dimensionen nicht angeben (array3D), aber wenn Sie wissen, dass sie sich nie ändern werden, ist es hilfreich zu wissen, welche Dimensionen Sie verwenden (array3Da).

Rownage
quelle
0

Sie müssen die interne Funktionsweise des Arrays verstehen. Das mehrdimensionale Array fungiert als eindimensionales Array, mit der Ausnahme, dass die Doppelindizierung in eine einzelne konvertiert wird.

Ihr gezacktes Array in c # ist ein Array von Objekten, die abwechselnd Arrays sind.

dvhh
quelle
0

Ich denke, dass die Speicherzuordnung von 2d-gezackten Arrays in C # wie 2d-Arrays in C ++ und C ist. Da 2d-gezackte Arrays einen Zeiger haben, der auf ein Array von Zeigern zeigt, zeigt jeder dieser Zeiger auf ein Array von Elementen (zum Beispiel ganzzahlige Elemente); wie dieser Code in C ++,

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

Die Speicherzuordnung des folgenden Codes entspricht der von 2d gezackten Arrays in C #. Aber ich bin mir nicht sicher, könnten Sie bitte mehr erklären, wenn ich falsch denke.

ARSD
quelle
0

Dieser Beitrag ist alt, aber hier sind meine Gedanken dazu.

Gezackte Arrays sind mehrdimensionale Arrays. Mehrdimensionale Arrays gibt es in zwei Varianten: rechteckig und gezackt. Rechteckige Arrays stellen einen n-dimensionalen Speicherblock dar, und gezackte Arrays sind Arrays von Arrays.

Rechteckige Anordnungen

Rechteckige Arrays werden durch Kommas deklariert, um jede Dimension zu trennen. Die folgende Anweisung deklariert ein rechteckiges zweidimensionales Array mit den Abmessungen 3 × 3:

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

Gezackte Arrays

Gezackte Arrays werden mit aufeinanderfolgenden eckigen Klammern deklariert, um jede Dimension darzustellen. Hier ist ein Beispiel für die Deklaration eines gezackten zweidimensionalen Arrays, wobei die äußerste Dimension 3 ist:

int[][] matrix = new int[3][];
Imir Hoxha
quelle
0

Stellen Sie sich für ein mehrdimensionales Array eine Box oder ein Rechteck vor. Jede Zeile hat die gleiche Länge und jede Spalte die gleiche Länge.

In einem gezackten Array sind die Zeilen und Spalten möglicherweise nicht gleich groß. Beispielsweise können die Spalten oder Zeilen unterschiedliche Größen haben. Dies würde zu einer Form führen, die möglicherweise keine gerade Linie an den Seiten wie ein Rechteck ist. Stattdessen können die Seiten gezackt sein .

Jetzt habe ich für dieses Beispiel 2 Dimensionen / 2 Arrays verwendet, aber dies gilt für mehr.

Roblem
quelle