Felder

In einem Feld kann eine beliebige, aber feste Anzahl gleichartiger Elemente verwaltet werden. Die Anzahl der Elemente wird dabei beim Erzeugen des Felds festgelegt und kann anschließend nicht mehr verändert werden.

Ungewohnt ist die Nummerierung der Elemente bei 0 beginnend und bei der Feldlänge-1 endend. Diese Form der Nummerierung findet in Java aber auch bei Zeichenketten konsequent Anwendung.

Wir werden im Folgenden das Verwalten primitiver Datentypen (vgl. Zahlen im obigen Beispiel) in einem Feld betrachten. Das Speichern gleichartiger Objekte in einem Feld wird im Abschnitt Felder im Kapitel Lineare Datenstrukturen behandelt.

Erzeugen eines Felds

Das folgende Beispiel zeigt zu Beginn die Syntax der Erzeugung eines Felds. Im Beispiel wird ein Feld der Länge 100 über int-Zahlen zunächst deklariert und anschließend initialisiert. Das Feld selbst ist aber zu diesem Zeitpunkt noch leer.

int[] meinfeld; // Deklaration
meinfeld = new int[100]; // Initialisierung

Als abkürzende Schreibweise können Deklaration und Initialisierung wieder zusammengefasst werden.

int[] meinfeld = new int[100]; // Deklaration + Initialisierung

Folgt die geplante Besetzung des Felds einer festen Systematik, hilft eine Schleife bei der Besetzung der einzelnen Feldelemente. Im folgenden Beispiel werden die natürlichen Zahlen 1, 2, 3 usw. in das Feld eingewiesen.

// Erzeuge Feld
int[] feld = new int[10];

// Besetze mit 1,2,3,...
for (int i=0; i<feld.length; i++) {
    feld[i] = i+1;           
}

Sind die Elemente des Feldes bei der Erzeugung bekannt und handelt es sich um ein eher kurzes Feld, so ist die folgende Kompaktschreibweise interessant, die Deklaration, Erzeugung und Initialisierung in einer Anweisung verbindet:

int[] feld = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 };

Durchlaufen eines Felds

Das nächste Beispiel setzt ein Feld über int-zahlen voraus und summiert bzw. multipliziert die enthaltenen Werte, unabhängig von der Länge des Feldes. Die Abfrage feld.length der Feldlänge sorgt leider oft für Verwirrung, da sie in Java im Gegensatz zu Zeichenketten für Felder nicht als Methodenaufruf mit anschließenden runden Klammern () realisiert ist.

int summe = 0;
for (int i=0; i<feld.length; i++) {
    summe = summe + feld[i];
}

int produkt = 1;
for (int i=0; i<feld.length; i++) {
    produkt = produkt * feld[i];
}

Zeichenkette in Feld verwandeln

Eine erste komplexere Aufgabe besteht darin, die in einer Zeichenkette enthaltenen Ziffern in ein Feld über int-Zahlen zu übertragen. Dazu wird im ersten Schritt ein Feld erzeugt, das genauso lang ist wie die Zeichenkette. In einem zweiten Schritt geht nun die Schleife Buchstabe für Buchstabe durch die Zeichenkette, konvertiert die einzelnen Ziffern in Zahlen (gemäß der ASCII-Tabelle entspricht 0 einer 48, 1 einer 49 usw.), wandelt sie durch die Subtraktion von 48 in die gewünschte Zahl zwischen 0 und 9 um und speichert sie an der gleichen Feldposition wie die Buchstabenposition.

String zeichenkette = "54678932";        

int n = zeichenkette.length();
int[] feld = new int[n];

for (int i=0; i<zeichenkette.length(); i++) {

    int zahl = (int) zeichenkette.charAt(i);
    zahl = zahl - 48; // ASCII-Code von 0 ist 48, von 1 ist 49 usw.
    feld[i] = zahl;

}

Zweidimensionale Felder

Zweidimensionale Felder eignet sich dazu, eine Tabelle bzw. Matrix gleichartiger Elemente zu verwalten. Das folgende Anwendungsbeispiel zeigt auf, wie bei dem Spiel Schiffe versenken die Schiffe einer Spielers in einer Matrix repräsentiert werden:

Der Spieler hat auf seinem Spielfeld (der "Seekarte") ein 2er-, ein 3er- und ein 4er-Schiff versteckt. Jedes Schiff ist durch die Koordinaten seiner Bestandteile (z.B. 0-2 und 0-3 für das 2er-Schiff) eindeutig festgelegt. Der Gegenspieler kann nun versuchen, durch einen Schuss auf eine vorgegebene Koordinate einen Teil eines Schiffes zu versenken.

Eine einfache Modellierung mit einem Java-Feld besteht darin, an Positionen mit einem Schiffsbestandteile eine 1, an allen anderen Koordinaten eine 0 abzuspeichern. Damit ergibt sich die Definition der Seekarte des Benutzers im Konstruktor der hier angegebenen Klasse.

Die erste Methode getroffen() überprüft, ob an der übergebenen Koordinate ein Schiffsbestandteil zu finden ist. Ist das der Fall, so wird er auf 0 gesetzt und damit "versenkt" und als Ergebnis true zurückgegeben. Ansonsten wird false zurückgegeben.

Die zweite Methode überprüft, ob auf der gesamten Seekarte alle Schiffe versenkt wurden (return true; am Ende) oder ob es noch mindestens ein Schiffsbestandteil auf der Seekarte (vorzeitiges return false;) gibt.

public class SchiffeVersenken {

    private int[][] meer = { { 0, 1, 1, 1, 1, 0 },
                             { 0, 0, 0, 0, 0, 0 },
                             { 1, 0, 0, 1, 1, 1 },
                             { 1, 0, 0, 0, 0, 0 } };

    public boolean getroffen(int zeile, int spalte) {
        if (meer[zeile][spalte] == 1)  {
            meer[zeile][spalte] = 0;
            return true;
        }
        else { return false; }
    }

    public boolean alleVersenkt() {
        for (int i=0; i<4; i++) {
            for (int j=0; j<6; j++) {
                if (meer[i][j]==1) {
                    return false;
                }
            }
        }
        return true;
    }

}

results matching ""

    No results matching ""