Was steht in einem 2D-Array, Zeilen oder Spalten an erster Stelle?

78

Wie kann man sich beim Erstellen eines 2D-Arrays daran erinnern, ob zuerst Zeilen oder Spalten angegeben werden?

Matt B.
quelle

Antworten:

89

Java wird als "Zeilenmajor" betrachtet, was bedeutet, dass zuerst Zeilen ausgeführt werden. Dies liegt daran, dass ein 2D-Array ein "Array von Arrays" ist.

Zum Beispiel:

int[ ][ ] a = new int[2][4];  // Two rows and four columns.

a[0][0] a[0][1] a[0][2] a[0][3]

a[1][0] a[1][1] a[1][2] a[1][3]

Es kann auch eher so dargestellt werden:

a[0] ->  [0] [1] [2] [3]
a[1] ->  [0] [1] [2] [3]

Die zweite Abbildung zeigt den Aspekt "Array of Arrays". Das erste Array enthält {a[0] and a[1]}, und jedes davon ist ein Array, das vier Elemente enthält {[0][1][2][3]}.

TL; DR Zusammenfassung:

Array[number of arrays][how many elements in each of those arrays]

Weitere Erklärungen finden Sie auch unter Arrays - 2-dimensional .

MrHappyAsthma
quelle
8
Ich habe die Visualisierung in dieser Antwort genossen.
Donato
1
Ich bin nicht überzeugt, dass entweder diese Antwort oder das Ausgangsmaterial überzeugend zeigt, dass Zeilen die erste Zahl sein sollten. Ich sehe keinen Grund, warum wir nicht zuerst Spalten und dann Zeilen erstellen können. Und wenn es eine Konvention ist, sehe ich hier nichts, was dies stark belegt.
Mathieu K.
1
Das OP hat nicht nach dem Grund gefragt, "warum" Java Zeilenmajor ist (was technisch nicht der Fall ist, aber am einfachsten zu konzipieren ist, wenn Sie sich das vorstellen und sich weniger Gedanken über das Speicherlayout machen). Sondern gefragt "Wie erinnert man sich?", Zuerst Zeilen konzeptionell anzugeben. Ich finde, Visualisierung ist der beste Weg, sich zu erinnern. Es sollte beachtet werden, dass Java nicht wirklich Zeilenmajor an sich verwendet, sondern wirklich Arrays von Arrays spezifiziert, wenn ich in meiner Antwort kurz darauf eingehe. Eine wirklich gute Visualisierung der Erklärung, wie es aufgebaut ist, finden Sie hier: stackoverflow.com/a/6631081/1366973
MrHappyAsthma
21

Während Matt B in gewissem Sinne wahr sein mag, kann es hilfreich sein, an ein mehrdimensionales Java-Array zu denken, ohne an geometerische Matrizen zu denken. Java-Multi-Dim-Arrays sind einfach Arrays von Arrays, und jedes Element der ersten "Dimension" kann eine andere Größe als die anderen Elemente haben oder tatsächlich ein Null-Sub-Array speichern. Siehe Kommentare unter dieser Frage

Kevin Welker
quelle
4
+1 für den Kontrast von ARRAY zu MATRIX! Arrays haben keine geometrische Definition. Wenn Sie glauben, dass ein 1D-Array vertikal ist, steht die Zeile an erster Stelle. Wenn Sie der Meinung sind, dass ein 1D-Array horizontal ist, steht col an erster Stelle. Bei Verwendung eines rechteckigen 2D-Arrays gibt es keine logische Unterscheidung, solange Sie es im gesamten Code gleich halten. UMSETZUNG NACH IHRER NUTZUNG! (Lassen Sie sich nicht das erste Element jedes Subarrays durchqueren, wenn Sie nur das erste Subarray durchqueren könnten)
Ron
15

Instinktiv denkt man geometrisch: horizontale (X) Achse und dann vertikale (Y) Achse. Dies ist jedoch bei einem 2D-Array nicht der Fall. Zuerst kommen Zeilen und dann Spalten.

Betrachten Sie die folgende Analogie: In der Geometrie geht man zur Leiter (X-Achse) und klettert darauf (Y-Achse). Umgekehrt steigt man in Java die Leiter (Zeilen) hinunter und geht weg (Spalten).

Matt B.
quelle
11
@ Luiggi Bitte beziehen Sie sich auf Es ist in Ordnung, Ihre eigene Frage zu stellen und zu beantworten, in der Sie (unter anderem) finden:To be crystal clear, it is not merely OK to ask and answer your own question, it is explicitly encouraged.
Matt B
1
Das gilt für Fragen wie diese oder diese gute Frage . Beachten Sie auch, dass beide Fragen ein Community-Wiki sind (die Stimmen tragen nicht zum Ansehen dieser Personen bei). Sie haben eine gute Erklärung und sollen den Menschen helfen und keinen Nutzen für sich selbst bringen.
Luiggi Mendoza
@ Zéychin Dies wäre wahrscheinlich besser im Chat geeignet.
Matt B
Es ist in Ordnung, sich die Transponierung vorzustellen. Wenn Sie sich also vorstellen, dass Spalten zuerst kommen, dann Zeilen, ist das wirklich in Ordnung. Dies ist bei in Java geschriebenen Matrixoperationsalgorithmen üblich.
Mohamed El-Nakib
Leider gibt es keinen Standard. Wenn Leute über Computerbildschirme sprechen, sagen sie "Breite nach Höhe", z. B. 1024 x 768 oder 1440 x 900. Aber wenn Leute über Rezeptkarten sprechen, sagen sie "3x5-Karte".
Dave Burton
5

Alles hängt von Ihrer Visualisierung des Arrays ab. Zeilen und Spalten sind Eigenschaften der Visualisierung (wahrscheinlich in Ihrer Vorstellung) des Arrays, nicht des Arrays selbst.

Es ist genau das gleiche wie zu fragen, ob die Nummer "5" rot oder grün ist.

Ich könnte es rot zeichnen, ich könnte es Gier zeichnen, oder? Farbe ist keine integrale Eigenschaft einer Zahl. Ebenso ist es für die Existenz dieses Arrays nicht erforderlich, ein 2D-Array als Raster aus Zeilen und Spalten darzustellen.

2D-Arrays haben nur eine erste und eine zweite Dimension . Alles, was mit der Visualisierung dieser Elemente zu tun hat , ist nur Ihr Geschmack.

Wenn ich ein Char-Array habe char[80][25], möchte ich es möglicherweise auf einer gedrehten Konsole drucken, sodass ich 25 Zeilen mit 80 Zeichen habe, die ohne Bildlauf auf den Bildschirm passen.

Ich werde versuchen, ein brauchbares Beispiel zu liefern, wenn die Darstellung eines 2D-Arrays als Zeilen und Spalten überhaupt keinen Sinn ergibt : Angenommen, ich benötige ein Array mit 1 000 000 000 Ganzzahlen. Mein Computer verfügt über 8 GB RAM, daher habe ich genügend Speicher dafür. Wenn Sie jedoch versuchen, die Ausführung auszuführen var a = new int[1000000000], wird höchstwahrscheinlich eine OutOfMemory-Ausnahme angezeigt. Das liegt an der Speicherfragmentierung - es gibt keinen aufeinanderfolgenden Speicherblock dieser Größe. Stattdessen können Sie mit Ihren Werten ein 2D-Array von 10 000 x 100 000 erstellen. Logischerweise handelt es sich um ein 1D-Array, daher möchten Sie es als eine einzelne Folge von Werten zeichnen und sich vorstellen. Aufgrund der technischen Implementierung handelt es sich jedoch um 2D.

Sasha
quelle
Interessanter Punkt! Ich hätte nie gedacht, wie ein Array von Arrays die Speicherfragmentierung verwenden würde. Um es weiter nach Hause zu fahren, würde die erste Zahl die Anzahl der Zeiger darstellen, und die zweite Zahl würde die Länge des Arrays darstellen, auf das jeder Zeiger zeigt (was auch bedeutet, dass die 2D-Version des 1D-Arrays tatsächlich MEHR Speicher für bereitstellt diese Zeiger).
4castle
@ 4castle, Sie haben Recht, ein gezacktes Array benötigt etwas mehr Speicher als ein gleichwertiges 2D-Array mit fester Größe, aber manchmal kann es Sie überraschenderweise vor der OutOfMemory-Ausnahme bewahren. Ich denke, das liegt daran, dass .NET versucht, große Objekte mithilfe aufeinanderfolgender Speicherblöcke zuzuweisen (nicht sicher, warum die Zuordnung von virtuellen Speicherblöcken das Problem nicht löst). Ich bin jedoch kein Experte für .NET-Speichermodelle. Nehmen Sie das also nicht als Tatsache.
Sasha
.NETZ? Dies war eine Java-Frage. Verwendet die Windows-JVM .NET?
4castle
@ 4castle, Entschuldigung, ich habe bereits vergessen, dass es sich um eine Java-Frage handelt, aber ich bin mir ziemlich sicher, dass es in .NET und JVM keine großen Unterschiede hinsichtlich der Darstellung gezackter und einfacher 1-dimensionaler Arrays im Speicher gibt.
Sasha
2

In Java gibt es keine mehrdimensionalen Arrays. Es gibt Arrays von Arrays. Damit:

int[][] array = new int[2][3];

Es besteht tatsächlich aus zwei Arrays mit jeweils drei Elementen.

Eng.Fouad
quelle
1
"... jeder hat 3 Arrays." Meinten Sie "jeder hat 3 Elemente ." ?
Muhammad Gelbana
1
Ich bin mir nicht sicher, ob dies die gestellte Frage beantwortet. Sind beim Deklarieren von Arrays von Arrays die Zeilen an erster Stelle oder die Spalten an erster Stelle?
Mathieu K.
1

Der beste Weg, sich daran zu erinnern, ob Zeilen oder Spalten an erster Stelle stehen, besteht darin, einen Kommentar zu schreiben und ihn zu erwähnen.

Java speichert ein 2D-Array nicht als Tabelle mit angegebenen Zeilen und Spalten, sondern als Array von Arrays, wie viele andere Antworten erklären. So können Sie entscheiden, ob die erste oder zweite Dimension Ihre Zeile ist. Abhängig davon müssen Sie nur das Array lesen.

Da ich selbst die ganze Zeit verwirrt bin, schreibe ich immer einen Kommentar, der mir sagt, welche Dimension des 2d-Arrays meine Zeile und welche meine Spalte ist.

Lord Luce
quelle
0

In Java werden die Zeilen zuerst erstellt, da ein zweidimensionales Array als zwei separate Arrays betrachtet wird. Beginnt mit dem Dimensionsarray der ersten Zeile 1.

Nour Lababidi
quelle
1
Dies ist in C # nicht Java. In der Programmiersprache Java ist ein mehrdimensionales Array ein Array, dessen Komponenten selbst Arrays sind. Daher kann jedes Komponentenarray eine andere Länge haben. Diese Notation, die Sie schreiben, befindet sich in C #, wodurch ein rechteckiges 2D-Array - das Java nicht hat - erzwungen wird. Dies entspricht dem Erzwingen, dass alle Komponenten-Arrays die gleiche Länge haben.
Mohamed El-Nakib
Vielen Dank :) Muhammad Annaqeeb
Nour Lababidi
Vielen Dank, ich kannte den Teil über den rechteckigen 2D-Array-Teil nicht. Das ist eine hilfreiche Antwort.
Nour Lababidi
Ich habe meine Antwort auf eine detailliertere und korrektere Antwort aktualisiert. Vielen Dank,
Nour Lababidi
0

In c ++ (entfernter, staubiger Speicher) war es meiner Meinung nach etwas einfacher, den Code zu betrachten und Arrays zu verstehen, als dies manchmal in Java der Fall ist. Beide sind Reihenmajor. Diese Illustration hat mir beim Verständnis geholfen.

Angesichts dieses Codes für ein 2d-Array von Zeichenfolgen ...

    String[][] messages; 
    messages = new String[][] {
        {"CAT","DOG","YIN","BLACK","HIGH","DAY"},
        {"kitten","puppy","yang","white","low","night"} 
    };
    
    int row = messages.length;
    int col = messages[0].length;
    

Wenn ich meine Ints so benenne, als wäre es ein 2D-Array (Zeile, Spalte), sehen wir die Werte.

row = (int) 2
col = (int) 6

Die letzten beiden Zeilen Code, wo wir versuchen , eine Größe zu bestimmen , und setzen Sie sie auf rowund colsieht nicht so intuitiv und es ist nicht unbedingt richtig.

Damit haben Sie hier wirklich zu tun (beachten Sie die neuen Variablennamen zur Veranschaulichung):

int numOfArraysIn = messages.length;
int numOfElementsIn0 = messages[0].length;
int numOfElementsIn1 = messages[1].length;

Wo messages.lengthsagt Ihnen, messageshält zwei Arrays. Ein Array von Arrays.

AND messages[x].lengthergibt dann die Größe jedes einzelnen Arrays im 0 1Inneren messages.

numOfArraysIn = (int) 2
numOfElementsIn0 = (int) 6
numOfElementsIn1 = (int) 6

Wenn wir mit einem für jede Schleife drucken ....

for (String str : messages[0])
        System.out.print(str);
for (String str : messages[1])
        System.out.print(str);

CATDOGYINBLACKHIGHDAYkittenpuppyyangwhitelownight

Der Versuch, die Klammern fallen zu lassen und so zu drucken, führt zu einem Fehler

for (String str : messages)
        System.out.print(str);

incompatible types: String[] cannot be converted to String

Das Obige ist wichtig, um beim Einrichten von Schleifen zu verstehen, .lengthmit denen der Schritt durch das Array begrenzt wird.

spencemw
quelle
0

In TStringGrid-Zellen steht die Eigenschaft Col an erster Stelle.

Property Cells[ACol, ARow: Integer]: string read GetCells write SetCells;

Die Zuordnung StringGrid1.cells[2, 1] := 'abcde';des Wertes wird also in der dritten Spalte der zweiten Zeile angezeigt.

Salem
quelle