Informatik

Zweidimensionale Felder

Ein Spielbrett, eine Tabelle, ein Bild aus Bildpunkten – all das hat Zeilen und Spalten. Dafür braucht man ein Feld, dessen Elemente selbst wieder Felder sind.

Anlegen und zugreifen

Schreibweise Bedeutung
int[][] gitter deklariert ein zweidimensionales Feld
new int[3][4] legt 3 Zeilen mit je 4 Spalten an
gitter[1][2] Zeile 1, Spalte 2
gitter.length Anzahl der Zeilen
gitter[0].length Anzahl der Spalten in Zeile 0

Merke dir die Reihenfolge: zuerst die Zeile, dann die Spalte. Wer das vertauscht, bekommt entweder falsche Werte oder einen Laufzeitfehler.

Ein zweidimensionales Feld ist in Wirklichkeit ein Feld von Feldern. Deshalb ist gitter[1] selbst ein int[].

Ein Bild dazu:

gitter
  ┌───────────────────────┐
0 │  5 │  0 │  0 │  0     │   ← gitter[0] ist ein int[] der Länge 4
  ├───────────────────────┤
1 │  0 │  0 │  7 │  0     │
  ├───────────────────────┤
2 │  0 │  0 │  0 │  9     │
  └───────────────────────┘
     0    1    2    3

Direkt mit Werten anlegen

Der Zugriff brett[i][i] läuft über die Hauptdiagonale.

a) Wie kommst du an die Gegendiagonale – also 3, 5, 7?

b) Wie an eine ganze Spalte, etwa die mittlere?

Auflösung

a) brett[i][brett.length - 1 - i]. Läuft i von 0 bis 2, läuft der zweite Index von 2 bis 0.

b) Man hält den Spaltenindex fest und lässt den Zeilenindex laufen:

for (int zeile = 0; zeile < brett.length; zeile++) {
    IO.println(brett[zeile][1]);
}

Es gibt keine Abkürzung dafür – Java kennt brett[1] als ganze Zeile, aber nichts Entsprechendes für Spalten.

Ein Spielbrett

Die Methode gewinner prüft in einer Schleife sowohl Zeilen als auch Spalten.

a) Erkläre, wie das funktioniert – wofür steht i in der einen und in der anderen Prüfung?

b) Warum steht überall zusätzlich die Bedingung mit dem Punkt?

c) Warum steht bei den Diagonalen pBrett[1][1] != '.' und nicht pBrett[0][0] != '.'?

Auflösung

a) Bei pBrett[i][0] ist i der Zeilenindex – die Prüfung läuft waagerecht. Bei pBrett[0][i] ist i der Spaltenindex – die Prüfung läuft senkrecht. Beide Male läuft dieselbe Zählvariable von 0 bis 2.

b) Ohne sie wären drei leere Felder ein Gewinn: '.' == '.' == '.' ist wahr. Man muss also ausschließen, dass das geprüfte Feld leer ist.

c) Beide Diagonalen laufen durch die Mitte. Ist die Mitte leer, kann keine Diagonale voll sein – ein Test statt zwei.

Aufgabe 1: Rechnen im Gitter

Ergänze die Methoden so, dass alle Tests grün werden.

Tipp 1: Die Grundschleife
for (int z = 0; z < pGitter.length; z++) {
    for (int s = 0; s < pGitter[z].length; s++) {
        // hier steht pGitter[z][s] zur Verfügung
    }
}

Beachte pGitter[z].length statt pGitter[0].length – so funktioniert es auch, wenn die Zeilen unterschiedlich lang sind.

Tipp 2: transponiert

Das neue Gitter hat so viele Zeilen, wie das alte Spalten hat – und umgekehrt:

int[][] neu = new int[pGitter[0].length][pGitter.length];

Und beim Kopieren gilt neu[s][z] = pGitter[z][s]. Die beiden Indizes tauschen die Plätze.

Lösung. Erfrage das Passwort bei deiner Lehrkraft.

Aufgabe 2: Ein Labyrinth

Ein Labyrinth lässt sich als zweidimensionales Feld von Zeichen darstellen: # ist eine Wand, . ist frei, S der Start und Z das Ziel.

Zeichne es mit Scratch for Java auf die Bühne.

a) Zeichne jede Zelle als Punkt: Wände dunkel, freie Felder hell, Start grün, Ziel rot.

b) Berechne die Bildschirmkoordinate aus Zeile und Spalte. Achte darauf, dass die y-Achse nach oben zeigt, die Zeilennummern aber nach unten wachsen.

Tipp: Die Umrechnung

Bei einer Zellgröße von 36 Pixeln und dem Plan in der Bühnenmitte:

int x = -130 + spalte * 36;
int y = 110 - zeile * 36;

Das Minus vor zeile ist der Kern: Zeile 0 soll oben liegen, y-Werte werden nach unten aber kleiner.

Lösung. Erfrage das Passwort bei deiner Lehrkraft.

Zusatzaufgabe

Java erlaubt Felder mit unterschiedlich langen Zeilen:

int[][] dreieck = new int[4][];
dreieck[0] = new int[1];
dreieck[1] = new int[2];
dreieck[2] = new int[3];
dreieck[3] = new int[4];

a) Erzeuge damit das pascalsche Dreieck bis zur zehnten Zeile. Jeder Wert ist die Summe der beiden darüber; die Ränder sind 1.

b) Gib es zentriert aus.

c) Erkläre, warum in diesem Fall die Bedingung s < pGitter[z].length unverzichtbar ist und s < pGitter[0].length das Programm zum Absturz bringen würde.


Selbsttest

Zweidimensionale Felder

Teilbare URL erstellen

Abschnitte auswählen