Implementierung von Multibehältern Inhaltsverzeichnis Hypertext-Version Algorithmen © APSIS GmbH

10. Steuerstrukturen

Seite 216

10.1. Alternativen

Seite 216

10.1.1. Verzweigungen

Seite 216

try {
	... // Normalfall
} catch (...) {
	... // Sonderfall
}
if (normalfall) {
	... // Normalfall
} else {
	... // Sonderfall
}
if (eimer.gefuellt()) // (10.1)
	Eimer.meldung("Eimer ist gefüllt");
else
	Eimer.meldung("Eimer ist leer");
if (! eimer.gefuellt()) // ¬
	Eimer.meldung("Eimer ist leer");
else
	Eimer.meldung("Eimer ist gefüllt"); 
if (a == b) // (10.2)
	a = 0;

Übung 10.1: Programmieren Sie eine rekursive Funktion fak, die die Fakultät einer gegebenen natürlichen Zahl berechnet. Sie wird als das Produkt der ersten n natürlichen Zahlen durch die Formel

n! = 1 × 2 × 3 × ... × (n-1) × n

definiert. Durch die Angabe verschiedener natürlicher Zahlen als Parameter der Funktion kann eine Wertetabelle zusammengestellt werden:

n 1 2 3 4 5 6 7 8 ...
n! 1 1 6 24 120 720 5040 40320 ...

Abb. 10.1: Fakultät

Die rekursive Berechnung ist auf Grund der Formel

n! = 1 × 2 × 3 × ... × (n-1) × n = (n-1)! × n

möglich: fak(n) == n * fak(n-1). Wir können diesmal keine Ausnahme für den Abbruch der Rekursion bei 1 verwenden; eine Einweg-Alternative ist nötig:

if (n > 1)
	... // Rekursion
else
	... // Abbruch

10.1.2. Fallunterscheidungen

Seite 218

int anzahl = finden(); // (10.3)
switch (anzahl) { // ¬
	case 0 : meldung("Nichts gefunden"); break;
	case 1 : meldung("Eins gefunden"); break;
	case 2 : meldung("Mehrere gefunden"); break;
	default: meldung("Fehler");
}
switch (zeichen) {
	case '?': case '.': case ',': case '!':
		meldung("Satzzeichen"); break;
	case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
	case '8': case '9':
		meldung("Ziffer"); break;
	default: meldung("anderes Zeichen");
}

10.1.3. Schachtelung von Alternativen

Seite 218

10.1.4. Kombination von Bedingungen

Seite 218

if (bedingung1 & bedingung2) ...
if (j > 0) // (10.4)
	if (i/j > k)
		... ; // Aktion
if (j > 0 && i/j > k)
	... ; // Aktion
if (bedingung1() || bedingung2()) ...

10.1.5. Erkennen einer Ausnahmesituation

Seite 219

public void fuellen() throws VollAusn { // (10.5)
	if (eimerGefuellt) // Ausnahmesituation erkannt ¬
		throw new VollAusn();
	else { // keine Ausnahme, erforderliche Aktion wird durchgeführt: ¬
		eimerGefuellt = true;
		if (eimerPos > 0) // wenn Eimer sichtbar
			Anim.eimerFuellen(); // Animation
	}
}
public Getraenk inhalt() throws LeerAusn {
	if (! eimerGefuellt) // Ausnahmesituation ¬
		throw new LeerAusn();
	else // Normalfall ¬
		return eimerInhalt;
}
package lehrbuch.kapitel8; // (10.6)
import lehrbuch.Aufz;
public class DiskreteMengeGen implements DiskreteMenge {
	private Class klasse; // registrierte Klasse ¬
	public DiskreteMengeGen(final Aufz reg) { // letzter Wert der Aufzählungsklasse
		klasse = reg.getClass(); // Methode getClass geerbt von Object ¬
		... // weiter im Programm (10.13)
	}
	private void pruefen(final Aufz element) {
		if (! klasse.isInstance(element)) // registrierte Klasse? ¬
			throw new GenFehler();
	}
	public void fuellen(final Aufz element) { // trägt element in die Menge ein
		pruefen(element);
		... // weiter im Programm (10.13)

Übung 10.2: Implementieren Sie die folgende Schnittstelle:

interface LogBehaelter { // (10.7)
	void fuellen(boolean wert) throws VollAusn;
	void entleeren() throws LeerAusn;
	boolean inhalt() throws LeerAusn;
	boolean gefuellt();
}

Erkennen Sie die Ausnahmesituationen mit Abfrage.

Übung 10.3: Implementieren Sie die Schnittstelle Warteschlange aus dem Kapitel 8.3.3. auf Seite 182 als Reihung (Ringpuffer). Im Gegensatz zur Übung 9.3 auf Seite 202 programmieren Sie die Operationen ohne Indexüberlauf:

public void eintragen(final Object element) throws VollAusn { // (10.8)
	if (anzahl == inhalt.length) // Anzahl der gespeicherten Elemente
		throw new VollAusn();
	else if (juengstes == inhalt.length)
		juengstes = 0; // auf das letzte Element folgt das Erste
	else
		juengstes ++; // ¬
	inhalt[juengstes] = element;
	anzahl ++;
}

Programmieren Sie einen menügesteuerten Testtreiber, mit dem Sie gerade und ungerade Zahlen in zwei getrennten Warteschlangen speichern können.

10.1.6. Vorbeugende Ausnahmebehandlung

Seite 221

void fuellenLinks() { // (6.16)
	try {
		links.fuellen(Eimer.WASSER);
	}
	catch (VollAusn ausnahme) {
		Eimer.meldung("Eimer voll");
	}
}
void fuellenLinks() { // (10.9)
	if (links.gefuellt()) // ¬
		Eimer.meldung("Eimer voll");
	else
		try {
			links.fuellen(Eimer.WASSER);
		}
		catch (VollAusn ausnahme) { System.out.println(ausnahme); } // nicht erwartet
}

10.2. Zählergesteuerte Wiederholungen

Seite 222

10.2.1. Zählschleifen

Seite 222

for (int i = 1; i <= anzahl; i++) ... // (10.10)
for (int i = 0; i < reihung.length; i++) ...
for (char zeichen = 'a'; zeichen <= 'z'; zeichen++)
	System.out.print(zeichen); // Alphabet wird angezeigt
for (char zeichen = 'z'; zeichen >= 'a'; zeichen--)
	System.out.println(zeichen); // Alphabet wird rückwärts angezeigt
int anzahl = System.in.read();
for (int i = 1; i <= anzahl; i++)
	System.out.println("Hallo"); // wird nie ausgeführt, wenn 0 eingegeben wurde ¬
int fak(int n) { // n>0 // (10.11)
	int produkt = 1;
	for (int zahl = 2; zahl <= n; zahl++) // ¬
		produkt *= zahl;
	return produkt;
}
for (int i = 0, j = reihung.length; j >= 0; i++, j--) ...
	// zwei Indizes laufen entgegengesetzt durch

Übung 10.4: Entwickeln Sie eine Prozedur (Methode einer aufgeschobenen Klasse), die die Wertetabelle einer beliebigen Funktion im gegebenen Intervall erstellt. Die zu berechnende Funktion ist eine Rückruffunktion. Die Ergebnisse sollen auch von Rückrufprozeduren übernommen werden:

interface Wertetabelle { // (10.12)
	void wertetabelle(final float untergrenze, final float obergrenze,
		final int anzahlSchritte);
	float funktion(final float x) throws KeinFunktionswertAusn; // abstract
		// die zu berechnende Funktion
	void ergebnis(final float x, final float y); // abstract
		// Übernahme der Ergebnisse
	void keinFunktionswert(final float x); // abstract
		// Übernahme, wenn kein Funktionswert berechnet werden kann
}

Die Schrittweite der Wertetabelle kann mit Hilfe der Formel berechnet werden:

Rufen Sie Ihre Prozedur in einem Testprogramm für die Funktion f(x) = 1/(x-k) und für einen Intervall [a, b] auf, dessen Grenzen (wie auch die Funktionskonstante k) interaktiv eingegeben werden. Die Übernahmeprozedur soll die Wertetabelle in zwei Spalten (x-Wert und y-Wert) ausgeben. An den x-Stellen, für die kein y-Wert berechnet werden kann (z.B. weil x=k), soll keinFunktionswert aufgerufen werden.

10.2.2. Implementierung diskreter Multibehälter

Seite 224

... // Anfang im Programm (10.6) // (10.13)
private boolean enthalten[]; // ¬
public DiskreteMengeGen(final Aufz reg) { // letzter Wert der Aufzählungsklasse
	klasse = reg.getClass(); // Methode getClass geerbt von Object
	Aufz letzter = reg.letzter();
	enthalten = new boolean[letzter.pos()+1]; // ¬
		// für jeden Aufzählungswert ein boolean
	for (int i = 0; i < enthalten.length; i++)
		enthalten[i] = false; // Menge ist zu Anfang leer ¬
}
public DiskreteMengeGen(final DiskreteMengeGen quelle) {
	klasse = quelle.klasse;
	enthalten = new boolean[quelle.enthalten.length];
	for (int i = 0; i < enthalten.length; i++)
		enthalten[i] = quelle.enthalten[i]; // ¬
}
public void fuellen(final Aufz element) { // trägt element in die Menge ein
	pruefen(element);
	enthalten[element.pos()] = true; // ¬
}
public void entfernen(final Aufz element) { // löscht element aus der Menge
	pruefen(element);
	enthalten[element.pos()] = false; // ¬
}
public boolean vorhanden(final Aufz element) {
	pruefen(element);
	return enthalten[element.pos()]; // ¬
}
...
class DiskreterSackGen implements DiskreterSack { // (10.14)
	private int[] anzahl; // ¬
	public DiskreterSackGen(final Aufz reg) {
		... // Registrierungsobjekt analysieren wie im Programm (10.6)
		anzahl = new int[letzter.pos()+1]; // für jeden Aufzählungswert ein int
		entleeren(); // Sack ist zu Anfang leer
	}
	public void entleeren() { // löscht alle Elemente aus dem Sack
		for (int i = 0; i < anzahl.length; i++)
			anzahl[i] = 0;
	}
	public void fuellen(final Aufz element) {
		pruefen(element); // wie im Programm (10.6)
		anzahl[element.pos()] ++; // ¬
	}
	public void entfernen(final Aufz element) throws KeinEintragAusn {
		pruefen(element);
		if (anzahl[element.pos()] == 0)
			throw new KeinEintragAusn();
		else
			anzahl[element.pos()] --; // ¬
	}
	public void alleEntfernen(final Aufz element) {
		pruefen(element);
		anzahl[element.pos()] = 0; // ¬
	}
	...

Übung 10.5: Jetzt können Sie Ihre Klasse aus der Übung 8.8 auf Seite 181 (SackAlgebra) programmieren. Testen Sie Ihre Implementierung.

10.2.3. Relevante Gleichheit

Seite 226

public void kopieren(Stapel quelle) throws VollAusn { // (10.15)
	try {
		StapelPol q = (StapelPol)quelle;
		inhalt = new Object[q.inhalt.length]; // neue Reihung erzeugen
		spitze = q.spitze;
		for (int index = 0; index < spitze; index++)
			inhalt[index] = q.inhalt[index];
	} catch (OutOfMemoryError ausnahme) {
		throw new VollAusn();
	}
}
public boolean gleich (Stapel stapel) {
	StapelPol s = (StapelPol)stapel;
	if (spitze != s.spitze)
		return false;
	for (int index = 0; index < spitze; index++) // ¬
		if (inhalt[index] != s.inhalt[index])
			return false;
	return true;
}

Abb. 10.2: Relevante Komponenten

10.2.4. Vektoren

Seite 227

Abb. 10.3: Vektoraddition

public interface Element { // (10.16)
	public void plus(final Element element);
	public void mult(final Element element);
	public Element zero(); // liefert Nullelement der Klasse (z.B. 0 für Integer)
}
public class Vektor { // (10.16)
	public Element [] vektor;
	public Vektor(int laenge) {
		vektor = new Element [laenge];
	}
	public void plus(final Vektor v) throws UnpassendAusn {
		if (vektor.length != v.vektor.length) { // vorbeugend
			throw new UnpassendAusn();
		}
		else {
			for (int index = 0; index < vektor.length; index++) // ¬
				vektor[index].plus(v.vektor[index]);
		}
	}
	public void mult(final Element zahl) { ... // multipliziert mit zahl, ähnlich
	public Element mult(final Vektor v) throws UnpassendAusn {
		if (vektor.length != v.vektor.length) // vorbeugende Ausnahmebehandlung
			throw new UnpassendAusn();
		else {
			Element summe = v.vektor[0].zero(); // mit Nullwert vorbesetzen
			for (int index = 0; index < vektor.length; index++) { // ¬
				Element produkt = vektor[index];
				produkt.mult(v.vektor[index]);
				summe.plus(produkt);
			}
			return summe;
		}
	}
	public void kopieren(final Vektor quelle) throws VollAusn {
		try {
			if (vektor.length != quelle.vektor.length) { // ungleiche Größe
				vektor = new Element[vektor.length];
					// neu belegen; throws OutOfMemoryError
			}
			for (int i = 0; i < vektor.length; i++) // elementweise kopieren ¬
				vektor[i] = quelle.vektor[i];
		} catch (OutOfMemoryError ausnahme) {
			throw new VollAusn();
		}
	}
	class UnpassendAusn extends Exception {}
}
for (int index = 0; index < vektor.length; index++)
	summe += vektor[index] * v.vektor[index];
class GanzElement implements Element { // (10.17)
	private int wert;
	public GanzElement() { wert = 0; }
	public GanzElement(final int wert) { this.wert = wert; }
	public void plus(final Element element) {
		GanzElement e = (GanzElement)element;
		wert += e.wert;
	}
	public void mult(final Element element) { ... // ähnlich
	public Element zero() { return new GanzElement(0); }
}
...
	Vektor ganzVektor = new Vektor(20); // Vektor für 20 Ganzzahlen
	ganzVektor.vektor[0] = new GanzElement(325);
	ganzVektor.vektor[1] = new GanzElement(-2315);
		... // usw., alle Vektorelemente werden besetzt
	ganzVektor.mult(new GanzElement(-1)); // Vorzeichen wird umgekehrt
class EimerElement implements Element { // (10.18)
	private Eimer wert;
	public EimerElement() { wert = new Eimer(); }
	public void plus(final Element element) {
		... // Summe zweier Eimer, wie auch immer sie errechnet wird
	public void mult(final Element element) { ... // Produkt ähnlich
	public Element zero() { ... // Nulleimer
}
	Vektor eimerVektor = new Vektor(5); // Platz für fünf Eimer
	... // Eimer werden im Vektor abgelegt, addiert sowie ihr Skalarprodukt errechnet

10.2.5. Matrizen

Seite 229

for (int zeile = 1; zeile <= 10; zeile++) { // (10.19)
	for (int spalte = 1; spalte <= 10; spalte++)
		System.out.print("\t" + zeile * spalte); // mit Tabulator
	System.out.println(); // nur Zeilenvorschub
}
public class Matrix { // (10.20)
	public Element[][] matrix;
	public Matrix(int breite, int hoehe) {
		matrix = new Element[breite][hoehe];
	}
	public void plus(final Matrix m) throws UnpassendAusn {
		if (matrix.length != m.matrix.length ||
				matrix[0].length != m.matrix[0].length)
			throw new UnpassendAusn();
		else {
			for (int zeile = 0; zeile < matrix.length; zeile++) // ¬
				for (int spalte = 0; spalte < matrix[0].length; spalte++) // ¬
					matrix[zeile][spalte].plus(m.matrix[zeile][spalte]);
		}
	}
	public void mult(final Element zahl) { ... // multipliziert mit zahl, ähnlich
	public void mult(final Matrix vektor) throws UnpassendAusn { ...
}

Übung 10.6: Programmieren Sie das Produkt zweier Matrizen nach der folgenden Regel: Das Element in der Zeile i und der Spalte j der Produktmatrix C ist das Skalarprodukt der i-ten Zeile der ersten Matrix A mit der j-ten Spalte der zweiten Matrix B. Hieraus ergibt sich folgende Formel für alle Elemente ci,j des Produkts zweier Matrizen mit den Elementen ai,j und bi,j :

d.h. jedes Element ci,j der Summenmatrix C (des Ergebnisses) mit den Indizes i und j ist die Summe der i-ten Zeile der ersten Matrix A und der j-ten Spalte der zweiten Matrix B. Aus dieser Formel ist ersichtlich, dass die Anzahl der Spalten in A gleich sein soll mit der Anzahl der Zeilen in B. (Die erste Dimension von A muss mit der zweiten Dimension von B gleich sein). Die Ergebnismatrix C hat so viele Zeilen wie A und so viele Spalten wie B: Wenn A ein n . l und B eine l . m Matrix ist, dann wird das Produkt C eine n . m Matrix werden.

Für die Programmierung des Matrixprodukts ist eine dreifach geschachtelte Wiederholung nötig. Schreiben Sie auch ein Testprogramm für Ihre Matrixklasse, in welchem Sie sie mit einer Ganzzahl- und für einen Bruchklasse ausprägen. Im Stapeltesttreiber sollen Sie die Matrizen (der Größe 2 .3 und 3 .4) als Konstanten definieren, ihre Summen und Produkte errechnen und am Bildschirm in Matrixform ausgeben.

10.3. Bedingungsgesteuerte Wiederholungen

Seite 230

10.3.1. Endlosschleifen

Seite 231

try {
	while (true); // leere Anweisung wird wiederholt ausgeführt, der Rechner tut nichts
} catch (TasteGedruecktAusn ausnahme) { ... // hier wird der Wartezustand beendet
int fakWert = 0; // (10.21)
double summand = 1.0;
double e = 1.0;
while (true) { // ¬
	fakWert ++;
	summand /= fakWert; // dividieren und zuweisen
	e += summand;
}

10.3.2. Rumpfgesteuerte Schleifen

Seite 231

while (true) { // (10.22)
	... // Eins-Block
if (abbruchbedingungErfuellt) break; // ¬
	... // Null-Block
}
double epsilon = 0.001; // (10.23)
while (true) {
	fakWert ++;
	summand /= fakWert;
if (summand < epsilon) break; // ¬
	e += summand;
}
while (true) {
	if ...
		... break; // nicht empfehlenswert
	...
}
public static float bruchzahlLesen() throws java.io.IOException { // liest float-Wert // (10.24)
	StringBuffer puffer = new StringBuffer(); // Puffer, Eingabe zu sammeln
	while (true) {
		int i = System.in.read(); // ein Zeichen lesen
		char c = (char)i; // Zeichen konvertieren
	if (c == '\n' || c == '\r') break; // Ende der Zeile? ¬
		puffer.append(c); // neues Zeichen am Ende des Puffers hinzufügen
	}
	int i = System.in.read(); // Rest der Eingabe verwerfen
	Float f = new Float(0).valueOf(new String(puffer)); // konvertieren
	return f.floatValue(); // float-Wert herauslesen
}

Übung 10.7: Schreiben Sie eine Java-Prozedur, das Zählen von Buchstaben durchführt. Lesen Sie von der Tastatur eine Zeile ein und zählen Sie die Häufigkeit jedes Buchstabens in einer Tabelle. Geben Sie zum Schluss das Ergebnis auf der Konsole aus.

Übung 10.8: Entwickeln Sie ein Java-Dialogprogramm für das folgende Problem der Zeichenanalyse: Die von der Tastatur eingegebenen Zeichen sollen analysiert und eine Statistik ausgegeben werden. Folgende Informationen werden verlangt:

  1. Die Anzahl der insgesamt eingelesenen Zeichen
  2. Die Anzahl der Klein- und Großbuchstaben
  3. Die Anzahl der Ziffern
  4. Die Anzahl der Vokale
  5. Die Anzahl der Konsonanten
  6. Die Anzahl der Sonderzeichen

10.3.3. Kopf- und fußgesteuerte Schleifen

Seite 233

while (true) { // leerer Eins-Block // (10.25)
if (abbruchbedingungErfuellt) break;
	... // Null-Block
};
while (! abbruchbedingungErfuellt) {
	... // Null-Block
}
do {
	... // Eins-Block
} while (! abbruchbedingungErfuellt);
double summand = 1.0;
while (summand >= epsilon) { // ¬
	fakWert ++;
	summand /= fakWert;
	e += summand;
};

10.3.4. Implementierung der Persistenzoperationen

Seite 234

public void speichern(String dateiname) throws DateiAusn { // (10.26)
	SeqDateiImpl datei = new SeqDateiImpl(dateiname);
	datei.neuBeschreiben();
	for (int i = 0; i < enthalten.length; i++) // ¬
		if (enthalten[i])
			datei.eintragen(new Character((char)i));
}
public void laden (final String dateiname) throws DateiAusn {
	try {
		entleeren();
		SeqDateiImpl datei = new SeqDateiImpl(dateiname);
		datei.zuruecksetzen();
		while (! datei.endeDerDatei()) { // ¬
			Character eintrag = (Character)datei.aktuellesElement();
			enthalten[(int)eintrag.charValue()] = true;
			datei.naechstesElement();
		}
	} catch (SeqDateiImpl.DateiendeAusn ausnahme) {
		throw new DateiAusn();
	}
}

Übung 10.9: Ergänzen Sie Ihre Lösung Übung 9.9 auf Seite 212 mit der Implementierung der Persistenzoperationen der Klasse PosListePol.

10.3.5. Abarbeitung einer Liste

Seite 234

public void suchen(final Object element) throws NichtGefundenAusn { // (10.27)
	try {
		do // suche erst vom nächsten Knoten an
			aktuell = aktuell.vorwaerts;
		while (aktuell.wert != element); // ¬
	} catch (NullPointerException ausnahme) {
			throw new NichtGefundenAusn();
	}
}
public void speichern(final String dateiname) throws DateiAusn { // const
	try {
		SeqDateiImpl datei = new SeqDateiImpl(dateiname);
		datei.neuBeschreiben();
		Knoten knoten = anfang;
		while (knoten != null) { // ¬
			datei.eintragen(knoten.wert); // wert ist Serializable
			knoten = knoten.vorwaerts;
		}
	} catch (Exception ausnahme) { throw new DateiAusn(); }
}

Übung 10.10: Implementieren Sie die Vergleichs- und die Zuweisungsmethode für die Stapelklasse StapelListe im Programm (9.10) auf Seite 204 mit Hilfe einer rumpfgesteuerten Schleife.

10.3.6. Dateiverarbeitung

Seite 235

public void mischen( // vorsortierte Dateien werden gemischt // (10.28)
		final String eingabe1, final String eingabe2, final String ausgabe) {
	IFile band1 = new IFile(), band2 = new IFile();
	OFile band3 = new OFile();
	Element puffer1 = new Element(), puffer2 = new Element(); // geordnet
	band1.open(eingabe1);
	band2.open(eingabe2);
	band3.open(ausgabe);
	band1.write(puffer1);
	band2.write(puffer2);
	while (!band1.eof() && !band2.eof()) { // ¬
		if (puffer1.kleiner(puffer2)) { // Operation für Element
			band3.write(puffer1); // den kleineren ausschreiben
			band1.write(puffer1); // und wieder einlesen
		}
		else {
			band3.write(puffer2);
			band2.write(puffer2);
		}
	} // band1 oder band2 ist zu Ende
	// Rest kopieren:
	while (!band1.eof()) { // ¬
		band3.write(puffer1);
		band1.write(puffer1);
	}
	while (!band2.eof()) { // ¬
		band3.write(puffer2);
		band2.write(puffer2);
	}
}

Übung 10.11: Ergänzen Sie die Übung 10.10 auf Seite 235 mit der Implementierung der Persistenzmethoden laden und speichern für die Stapelklasse.

10.3.7. Assoziativtabellen

Seite 236

  • int hash(final schluessel); // const schluessel
  • Abb. 10.4: Assoziativtabelle

  • int verschiebungen();
  • Übung 10.12: Programmieren Sie einen Assoziativspeicher als Assoziativtabelle. Die Schnittstelle eines (allgemeinen) Assoziativspeichers finden Sie im Programm (8.27) auf Seite 192. Definieren Sie nun die Struktur der Klasse AssoTab und programmieren Sie ihre Operationen. Prägen Sie Ihren Assoziativspeicher für ein Telefonbuch aus, in dem Sie den Nachnamen als Schlüssel, Vornamen und Telefonnummer als Element speichern. Die Größe der Tabelle sollte als Konstruktorparameter angegeben werden. Schreiben Sie dazu ein einfaches Dialogtestprogramm. Vergessen Sie dabei die Persistenzoperationen nicht: Über einen Menüpunkt sollte Ihre Tabelle in eine Datei, deren Name eingegeben wird, gespeichert bzw. von dort gelesen werden können. Hierzu muss die Elementklasse die Schnittstelle java.io.Serializable implementieren.

    10.3.8. Verwendung der Schleifenarten

    Seite 237

    while (! dateiende()) { // (10.29)
    	element.lesen();
    	element.bearbeiten();
    	element.schreiben();
    }
    referenz = anker;
    while (referenz != null) {
    	bearbeiten(referenz.wert);
    	referenz = referenz.verbindung;
    }
    while (true) {
    	element.bearbeiten();
    	element.lesen();
    if (keineMehrDa()) break;
    }
    while (true) {
    	element.lesen();
    if (element.endekriterium()) break;
    	element.bearbeiten();
    }

    10.3.9. Gleichwertigkeit von Wiederholungen

    Seite 238

    while (true) { // (10.30)
    	... // Eins-Block
    if (abbruchbedingungErfuellt) break;
    	... // Null-Block
    };
    	... // Eins-Block verdoppelt
    while (! abbruchbedingungErfuellt) {
    	... // Null-Block
    	... // Eins-Block
    };
    boolean weiter = true;
    while (weiter) {
    		... // Eins-Block
    	weiter = ! abbruchbedingungErfuellt;
    	if(weiter)
    		... // Null-Block
    };
    for (int i = anfang; i <= ende; i++) // (10.31)
    	... // Rumpf
    int i = anfang;
    while (i <= ende) {
    	... // Rumpf
    	i ++;
    };

    10.3.10. Hierarchie der Algorithmen

    Seite 239


    Implementierung von Multibehältern Inhaltsverzeichnis Hypertext-Version Algorithmen © APSIS GmbH