Algorithmische Grundstrukturen IFB 2002 Klaus Becker
Algorithmisches Problemlösen Teil 1 Algorithmisches Problemlösen
Problem Eine Lokomotive soll die auf Gleis A (oben) befindlichen Wagen in umgekehrter Reihenfolge auf Gleis B (unten) abstellen. AZ B ? ZZ B Problem: AZ ZZ Barriere Ausgangszustand Zielzustand ZZ
Problemspezifikation AZ ZZ Problemspezifikation: vollständige und eindeutige Beschreibung des Ausgangs- und Zielzustandes
Problemlösen mit einem Prozessor Lokomotive: fahren; ankoppeln; abkoppeln; Weiche stellen; .. AZ ZZ Prozessor: legt die zulässigen Operationen fest
Algorithmus Algorithmus: Problemlösebeschreibung AZ ZZ Algorithmus: endliche Folge von eindeutig ausführbaren Anweisungen zur Lösung des Problems
Korrektheit Spezifikation: AZ ZZ Korrektheit bzgl. einer Spezifikation: Algorithmus überführt tatsächlich den AZ in den ZZ (für alle möglichen AZ-Konstellationen)
Effizienz Spezifikation: AZ ZZ Effizienz: Algorithmus löst das Problem mit möglichst geringen Aufwand
Ziele Wie sind Algorithmen zur Lösung von Problemen aufgebaut? „Grundbausteine von Algorithmen“ Wie formuliert man Algorithmen, so dass sie vom Computer ausgeführt werden können? „Grundelemente von Programmiersprachen“ Einschränkungen - imperative Algorithmen - Pascal als Programmiersprache
Teil 2 Variablenkonzept
Mäusepopulation Wir betrachten die Entwicklung einer Mäusepopulation. Die Population wird unterteilt in junge Mäuse, erwachsene Mäuse und alte Mäuse. Wir gehen von den folgenden Annahmen aus: - In einem Simulationsschritt wird die Hälfte der jungen Mäuse erwachsen. - In einem Simulationsschritt erzeugt jede erwachsene Maus (im Durchschnitt) 4 junge Mäuse. Nur ein Drittel der erwachsenen Mäuse wird in einem Simulationsschritt alt. - In einem Simulationsschritt erzeugt jede alte Maus (im Durchschnitt) 2 junge Mäuse. Alle alten Mäuse sterben innerhalb dieses Simulationsschrittes.
Entwicklung der Mäusepopulation Schritt Anzahl der Anzahl der Anzahl der jungen Mäuse erw. Mäuse alten Mäuse 0 6 9 12 1 60 = 4*9 + 2*12 3 = 6:2 3 = 9:3 2 18 = 4*3 + 2*3 30 = 60:2 1 = 3:3 3 122 = 4*30 + 2*1 9 = 18:2 10 = 30:3 4 56 = 4*9 + 2*10 61 = 122:2 3 = 9:3 5 250 = 4*61 + 2*3 28 = 56:2 20,3.. = 61:3 ... Ziel: Automatisierung der Berechnung Berechnungsmodell
Register (Speicherplatz) Berechnungsmodell Berechnungsmodell: Variablen-basierte Registermaschine Schritt : integer-Register jung : 6.0 real-Register erwachsen : ... alt : ... Variable (Name des Registers) Register (Speicherplatz)
Variablendeklaration Eine Variablendeklaration legt die zu benutzenden Register fest. Schritt : integer Schritt : ... jung : real jung : ... erwachsen : real erwachsen : ... alt : real alt : ... Variable (Name des Registers) Datentyp (legt zulässigen Registerinhalte fest) Register (Speicherplatz)
Variablenwert Der Variablenwert stellt den Registerinhalt dar. Schritt : Variablenzustand: Gesamtheit der Variablenwerte jung : 6.0 erwachsen : 9.0 alt : ... Kurzschreibweise für Variablenzustände: {Schritt: [0]; jung: [6.0]; erwachsen: [9.0]; alt: [...]}
Wertzuweisung Mit Wertzuweisungen werden Variablenwerte verändert. {Schritt: [0]; jung: [6.0]; erwachsen: [...]; alt: [...]} vorher alt := 12.0 Wertzuweisung {Schritt: [0]; jung: [6.0]; erwachsen: [...]; alt: [12.0]} nachher {Schritt: [0]; jung: [6.0]; erwachsen: [...]; alt: [12.0]} vorher erwachsen := jung / 2 Wertzuweisung {Schritt: [0]; jung: [6.0]; erwachsen: [3.0]; alt: [12.0]} nachher {Schritt: [0]; jung: [6.0]; erwachsen: [3.0]; alt: [12.0]} vorher Schritt := Schritt +1 Wertzuweisung {Schritt: [1]; jung: [6.0]; erwachsen: [3.0]; alt: [12.0]} nachher
Wertzuweisung Syntax: Semantik: <Variable> := <Term> Der Wert des Terms wird bzgl. des aktuellen Variablenzustands ermittelt und der Variablen als neuer Wert zugewiesen. (Überschreiben des Registers) Beachte: Variable und Term müssen typkonform sein. Beispiel: Schritt := Schritt +1 { Schritt: [3]; ...} Schritt := Schritt +1 4 { Schritt: [4]; ...}
Problemspezifikation AZ: Die eingeführten Variablen beschreiben die Anfangspopulation. {Schritt: [0]; jung: [6.0]; erwachsen: [9.0]; alt: [12.0]} EZ: Die Variablen beschreiben die Population nach einem Simulationsschritt.. {Schritt: [1]; jung: [60.0]; erwachsen: [3.0]; alt: [3.0]} Erweiterung: Die Anfangspopulation soll vom Benutzer vorgegeben werden. Die neue Population nach einem Simulationsschritt soll dem Benutzer angezeigt werden.
Lösungsvorschlag 1 beachte: Der Algorithmus ist nicht korrekt! Wertzuweisung Schritt := Schritt + 1 jung := erwachsen*4 + alt*2 erwachsen := jung / 2 alt := erwachsen / 3 Variablenzustand - Trace-Tabelle Schritt jung erw. alt 0 6.0 9.0 12.0 1 6.0 9.0 12.0 1 60.0 9.0 12.0 1 60.0 30.0 12.0 1 60.0 30.0 10.0 beachte: Der Algorithmus ist nicht korrekt!
Lösungsvorschlag 2 beachte: Reihenfolge der Wertzuweisungen Schritt := Schritt + 1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf Variablenzustand - Trace-Tabelle Schritt jung erw. alt hilf 0 6.0 9.0 12.0 1 6.0 9.0 12.0 1 6.0 9.0 12.0 60.0 1 6.0 9.0 3.0 60.0 1 6.0 3.0 3.0 60.0 1 60.0 3.0 3.0 60.0 beachte: Reihenfolge der Wertzuweisungen
EVA-Prinzip: Eingabe - Verarbeitung - Ausgabe Algorithmus E Eingabe: jung, erwachsen, alt Schritt := 0 Schritt := Schritt + 1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf Ausgabe: Schritt, jung, erwachsen, alt V A EVA-Prinzip: Eingabe - Verarbeitung - Ausgabe
Pascal-Programm PROGRAM Maeuse1; VAR Schritt : integer; jung, erwachsen, alt : real; hilf : real; BEGIN { Eingaben und Initialisierungen } ... { Berechnungen } Schritt := Schritt+1; hilf := erwachsen*4 + alt*2; alt := erwachsen/3; erwachsen := jung/2; jung := hilf; { Ausgaben } END.
Programmstruktur Programmkopf Deklarationsteil - erzeugt die Register PROGRAM Maeuse1; VAR <Variablendeklaration> ; BEGIN ... { Kommentar } <Anweisung> ; END. Programmkopf Deklarationsteil - erzeugt die Register Anweisungsteil - verändert die Registerinhalte
Basisanweisungen Eingabeanweisung: read(ln) Wertzuweisung: := BEGIN { Eingaben und Initialisierungen } writeln('Geben Sie die Anfangspopulation ein.'); write('Anzahl der jungen Mäuse : '); readln(jung); write('Anzahl der erwachsenen Mäuse : '); readln(erwachsen); write('Anzahl der alten Mäuse : '); readln(alt); Schritt := 0; { Berechnungen } Schritt := Schritt+1; ... { Ausgaben } writeln('Anzahl der Schritte: ', Schritt); writeln('Anzahl der jungen Mäuse : ', jung:6:2); writeln('Anzahl der erwachsenen Mäuse : ', erwachsen:6:2); writeln('Anzahl der alten Mäuse : ', alt:6:2); END. Eingabeanweisung: read(ln) Wertzuweisung: := Ausgabeanweisung: write(ln)
Anweisungen - eine Übersicht Basisanweisung ... Kontrollanweisung Wertzuweisung Eingabeanweisung Ausgabeanweisung ...
Teil 3 Kontrollstrukturen
Sequenzbildung {Eingabe und Initialisierung} Eingabe: jung, erwachsen, alt Schritt := 0 {Verarbeitung} Schritt := Schritt + 1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf {Ausgabe} Ausgabe: Schritt, jung, erwachsen, alt
Sequenz PASCAL Struktogramm PAP ... BEGIN <Anweisung1>; <Anweisung2>; <Anweisung3>; ... END Anweisung1 Anweisung2 Anweisung3 ... Anweisung1 Anweisung2 Anweisung3 ...
Problemspezifikation Ziel: Die Entwicklung der Mäusepopulation soll über 20 Schritte verfolgt werden. Spezifikation Eingaben: Die Werte der Anfangspopulation werden eingegeben. Z B.: jung: 6.0; erwachsen: 9.0; alt: 12.0 Ausgaben: Die Populationswerte nach 20 Simulationsschritten werden ausgegeben.
Wiederholung Anweisung {Eingaben / Initialisierung} Schritt := Schritt + 1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf ... Variablenzustand Schritt jung erw. alt hilf 0 6.0 9.0 12.0 1 6.0 9.0 12.0 1 6.0 9.0 12.0 60.0 1 6.0 9.0 3.0 60.0 1 6.0 3.0 3.0 60.0 1 60.0 3.0 3.0 60.0 2 60.0 3.0 3.0 60.0 2 60.0 3.0 3.0 18.0 2 60.0 3.0 1.0 18.0 2 60.0 30.0 1.0 18.0 2 18.0 30.0 1.0 18.0 ...
Wiederholung Eingabe: jung, erwachsen, alt gesamt := jung + erwachsen + alt Schritt := 0 SOLANGE Schritt < 20 Schritt := Schritt +1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf gesamt := jung + erwachsen + alt Ausgabe: jung, erwachsen, alt, gesamt
Wiederholung Eingabe: ...; gesamt := ...; Schritt := 0 falsch wahr Schritt := Schritt +1 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf gesamt := jung + erwachsen + alt Ausgabe: jung, erwachsen, alt, gesamt
Mäusepopulation Die Entwicklung der Mäusepopulation wird wie folgt abgeändert: Sind weniger als 1000 Mäuse in der Population, so verhalten sich die Mäuse wie bisher. Ab 1000 Mäuse wird das Futter knapp. Alte Mäuse erzeugen dann keine jungen Mäuse mehr und jede erwachsene Maus erzeugt (im Durchschnitt) nur noch 1.5 junge Mäuse. Spezifikation: wie oben Schritt < 100
Fallunterscheidung Eingabe: jung, erwachsen, alt gesamt := jung + erwachsen + alt Schritt := 0 SOLANGE Schritt < 20 Schritt := Schritt +1 gesamt < 1000 wahr falsch hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf hilf := erwachsen*1.5 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf gesamt := jung + erwachsen + alt
Schritt := 0; ... ; gesamt := jung + erwachsen + alt Fallunterscheidung Schritt := 0; ... ; gesamt := jung + erwachsen + alt falsch Schritt < 20 wahr Schritt := Schritt + 1 wahr falsch gesamt < 1000 hilf := erwachsen*4 + alt*2 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf hilf := erwachsen*1.5 alt := erwachsen / 3 erwachsen := jung / 2 jung := hilf gesamt := jung + erwachsen + alt ...
Pascal-Programm ... BEGIN {Eingaben und Initialisierung}; WHILE Schritt < 20 DO Schritt := Schritt+1; IF gesamt < 1000 THEN hilf := erwachsen*4 + alt*2; END ELSE hilf := erwachsen*1.5; END; gesamt := jung + erwachsen + alt; {Ausgaben} END.
Kontrollstrukturen Kontrollstrukturen dienen dazu, den genauen Ablauf von Aktionen festzulegen. Ablaufmuster: - sequentieller Ablauf - wiederholter Ablauf - bedingter Ablauf - paralleler Ablauf - ereignisgesteuerter Ablauf Kontrollstrukturen: - Sequenz - Wiederholung - Fallunterscheidung / Auswahl
Anweisungen - eine Übersicht Basisanweisung ... Kontrollanweisung Wertzuweisung Eingabeanweisung Ausgabeanweisung ... Sequenzanweisung Wiederholungs-anweisung Fallunterscheidungs-anweisung
Schachtelung von Anweisungen BEGIN readln(jung); ... WHILE Schritt < 20 DO Schritt := Schritt+1; IF gesamt < 1000 THEN hilf := erwachsen*4 + alt*2; END ELSE hilf := erwachsen*1.5; END; gesamt := jung + erwachsen + alt; writeln('Anzahl der Schritte: ', Schritt); END.
Übungen - Aufgabe 1 AZ ZZ Formulieren Sie (umgangssprachlich) einen Algorithmus zur Lösung des Rangierproblems. Die Lokomotive kann folgende „Operationen“ ausführen: vorwärts / rückwärts fahren; ankoppeln; abkoppeln; Weiche umstellen. Der Algorithmus soll für eine beliebige Anzahl von Waggons korrekt sein.
Übungen - Aufgabe 2 Abstraktes Rangierproblem: Gegeben sind drei Variablen A, B und C. Die Werte der Variablen sollen wie folgt ausgetauscht werden: A: a B: b C: c AZ: { A: [a]; B: [b]; C: [c] } EZ: { A: [c]; B: [a]; C: [b] }
Übungen - Aufgabe 3 Vertauschungsproblem: Die Werte der Variablen A und B sollen ausgetauscht werden: AZ: { A: [a]; B: [b] } EZ: { A: [b]; B: [a] } Beurteile die folgenden Algorithmen hinsichtlich Korrektheit und Aufwand. B := A A := B C := A D := B A := D B := C H := A A := B B := H A := A - B B := A + B A := B - A
Übungen - Aufgabe 4 Mäusepopulation: Der Algorithmus / das Programm zur Beschreibung der Entwicklung der Mäusepopulation soll wie folgt abgeändert werden: A) Der jeweilige Populationszustand (Anzahl der jungen, erwachsenen und alten Mäuse) soll nach jedem Schritt ausgegeben werden. B) Nach jedem Schritt sollen die prozentualen Anteile der jungen, erwachsenen und alten Mäuse an der momentanen Gesamtpopulation berechnet und ausgegeben werden.
Übungen - Aufgabe 5 Trace-Tabelle: Erstellen Sie eine Trace-Tabelle für die Eingaben A 10 und B 24. Was leistet der folgende Algorithmus? BEGIN Readln(A); Readln(B); REPEAT WHILE A > B DO A := A – B; WHILE B > A DO B := B – A; UNTIL A = B Writeln(A); END
Übungen - Aufgabe 6 Problem: Eine Folge positiver Zahlen soll eingelesen und ihr Minimum bestimmt und ausgegeben werden. Das Ende der Folge wird durch die Eingabe der Zahl 0 erkannt. Bsp.: Eingabefolge: 5, 3, 6, 7, 0 Ausgabe: 3 Eingabefolge: 0 Ausgabe: 0 Ist der folgende Algorithmus korrekt? Ändern Sie ihn gegebenenfalls geeignet ab. Eingabe: z min := z SOLANGE z > 0 Eingabe: z WENN z < min DANN min := z Ausgabe: min
Übungen - Aufgabe 7 Mit Hilfe eines Programms soll die Kapitalentwicklung bei einer Verzinsung mit einem festen Zinssatz von p = 3% berechnet werden. Problemspezifikation 1: Eingaben : Anfangskapital, Anzahl der Jahre Ausgabe : erreichtes Endkapital Problemspezifikation 2: Eingaben : Anfangskapital, Endkapital Ausgabe : Anzahl der benötigten Jahre Erstellen Sie entsprechende Algorithmen / Programme.
Übungen - Aufgabe 8 Für Fortgeschrittene: Ziel ist es, das Spiel „17 und 4“ zu simulieren. Das Spiel soll wie folgt funktionieren: In jedem Spielzug wird eine Karte mit einer Zahl aus dem Bereich [1;...;11] bestimmt und auf einen Kartenstapel gelegt. Der Spieler kann nach jedem Spielzug entscheiden, ob er aufhört oder weiter spielt. Ist die Summe der Zahlen der Karten des Stapels größer als 21, so hat der Spieler verloren. Hört der Spieler bei einer Stapelsumme kleiner oder gleich 21 auf, so wird die nächste Karte gezogen. Ist die neue Stapelsumme immer noch kleiner oder gleich 21, so hat der Spieler verloren, andernfalls gewonnen. Erstellen Sie einen passenden Algorithmus.
Aufgabe 1 - Lösungsvorschlag Solange noch mindestens ein Waggon auf Gleis A steht: vorwärts fahren; ankoppeln; rückwärts fahren; Weiche umstellen; abkoppeln; Weiche umstellen.
Aufgabe 2 - Lösungsvorschlag Abstraktes Rangierproblem: Gegeben sind drei Variablen A, B und C. Die Werte der Variablen sollen wie folgt ausgetauscht werden: A: a B: b C: c AZ: { A: [a]; B: [b]; C: [c] } H := A A := C C := B B := H EZ: { A: [c]; B: [a]; C: [b] }
Aufgabe 3 - Lösungsvorschlag Vertauschungsproblem: Die Werte der Variablen A und B sollen ausgetauscht werden: AZ: { A: [a]; B: [b] } EZ: { A: [b]; B: [a] } B := A A := B C := A D := B A := D B := C H := A A := B B := H A := A - B B := A + B A := B - A nicht korrekt Korrekt größter Aufwand Korrekt kleinster Aufwand Korrekt nur für Zahl-Variablen
Aufgabe 5 - Lösungsvorschlag Anw. A B Readln(A) 10 Readln(B) 10 24 A > B ? F B > A ? W B := B - A 10 14 B > A ? W B := B - A 10 4 B > A ? F A = B ? F A > B ? W A := A - B 6 4 A > B ? W A := A - B 2 4 A > B ? F B > A ? W B := B - A 2 2 B > A ? F A = B ? W Writeln(A) --> 2 BEGIN Readln(A); Readln(B); REPEAT WHILE A > B DO A := A – B; WHILE B > A DO B := B – A; UNTIL A = B Writeln(A); END
Aufgabe 6 - Lösungsvorschlag Problem: Eine Folge positiver Zahlen soll eingelesen und ihr Minimum berechnet und ausgegeben werden. Das Ende der Folge wird durch die Eingabe der Zahl 0 erkannt. Eingabe: z min := z SOLANGE z > 0 Eingabe: z WENN z < min DANN min := z Ausgabe: min Eingabe: z min := z SOLANGE z > 0 WENN z < min DANN min := z Eingabe: z Ausgabe: min Die Eingabefolge 3, 0 liefert die Ausgabe 0. Der Algorithmus ist also nicht korrekt. Die Eingabefolge 3, 0 liefert jetzt die Ausgabe 3 - so, wie es sein soll.
Teil 4 Schleifentypen
Kapitalberechnungen Mit Hilfe eines Programms soll die Kapitalentwicklung bei einer Verzinsung mit einem festen Zinssatz von p = 3% berechnet werden. Problemspezifikation 1: Eingaben : Anfangskapital, Anzahl der Jahre Ausgabe : erreichtes Endkapital Problemspezifikation 2: Eingaben : Anfangskapital, Endkapital Ausgabe : Anzahl der benötigten Jahre
Programm „Kapital1“ ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Kapital); write('Anzahl der Jahre : '); readln(Jahre); { Berechnungen } Zaehler := 1; WHILE Zaehler <= Jahre DO Kapital := Kapital + Kapital * p/100; Zaehler := Zaehler + 1; END; { Ausgaben } writeln('Endkapital : ', Kapital:8:2); readln; END.
Programm „Kapital2“ ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Kapital); write('Anzahl der Jahre : '); readln(Jahre); { Berechnungen } FOR Zaehler := 1 TO Jahre DO Kapital := Kapital + Kapital * p/100; { Ausgaben } writeln('Endkapital : ', Kapital:8:2); readln; END.
Programm „Kapital3“ ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Kapital); write('Anzahl der Jahre : '); readln(Jahre); { Berechnungen } FOR Zaehler := JAHRE DOWNTO 1 DO Kapital := Kapital + Kapital * p/100; { Ausgaben } writeln('Endkapital : ', Kapital:8:2); readln; END.
Zählschleife Eingabe: Kapital, Jahre Eingabe: Kapital, Jahre Zaehler := 1 SOLANGE Zaehler <= Jahre Zaehler := 1 Kapital := Kapital + ... Zaehler := Zaehler + 1 falsch Zaehler<=Jahre Ausgabe: Kapital wahr Kapital := Kapital + ... Zaehler := Zaehler + 1 Eingabe: Kapital, Jahre FÜR Zaehler VON 1 BIS Jahre Kapital := Kapital + ... Ausgabe: Kapital Ausgabe: Kapital
Programm „Kapital4“ ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Anfangskapital); write('Endkapital : '); readln(Endkapital); { Berechnungen } Kapital := Anfangskapital; Jahre := 0; WHILE Kapital < Endkapital DO Kapital := Kapital + Kapital * p/100; Jahre := Jahre + 1; END; { Ausgaben } writeln('Anzahl der Jahre : ', Jahre); readln; END.
Programm „Kapital5“ ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Anfangskapital); write('Endkapital : '); readln(Endkapital); { Berechnungen } Kapital := Anfangskapital; Jahre := 0; REPEAT Kapital := Kapital + Kapital * p/100; Jahre := Jahre + 1; UNTIL Kapital >= Endkapital; { Ausgaben } writeln('Anzahl der Jahre : ', Jahre); readln; END.
Wiederholung Wiederholung mit Anfangsbedingung Eingabe: AKapital, EKapital Eingabe: AKapital, EKapital Kapital := AKapital Kapital := AKapital Jahre := 0 Jahre := 0 SOLANGE Kapital < EKapital Kapital := Kapital + ... Jahre := Jahre + 1 Kapital := Kapital + ... Jahre := Jahre + 1 BIS Kapital >= EKapital Ausgabe: Jahre Ausgabe: Jahre Wiederholung mit Anfangsbedingung Wiederholung mit Endbedingung
Kapital>=EKapital Wiederholung Eingabe: AKapital, EKapital Eingabe: AKapital, EKapital Kapital := AKapital Kapital := AKapital Jahre := 0 Jahre := 0 falsch Kapital<EKapital Kapital := Kapital + ... Jahre := Jahre + 1 wahr Kapital := Kapital + ... Jahre := Jahre + 1 falsch Kapital>=EKapital wahr Ausgabe: Jahre Ausgabe: Jahre
Wiederholung mit Anfangsbedingung PASCAL Struktogramm PAP WHILE <Bedingung> DO <Anweisung> SOLANGE Bed. Anweisung f Bed. w Anw Beachte: Erst Bedingung überprüfen, dann Anweisung ausführen!
Wiederholung mit Endbedingung PASCAL Struktogramm PAP REPEAT <Anweisung> UNTIL <Bedingung> Anweisung BIS Bedingung Anw. Bed. f w Beachte: Erst Anweisung ausführen, dann Bedingung überprüfen! Die Anweisung wird mindestens einmal ausgeführt.
Achtung: Endlosschleife ... BEGIN { Eingaben } write('Anfangskapital : '); readln(Anfangskapital); write('Endkapital : '); readln(Endkapital); { Berechnungen } Kapital := Anfangskapital; Jahre := 0; WHILE Kapital < Endkapital DO Jahre := Jahre + 1; END; { Ausgaben } writeln('Anzahl der Jahre : ', Jahre); readln; END.
Fallunterscheidungstypen Teil 5 Fallunterscheidungstypen
Rückerstattungsberechnungen Mit Hilfe eines Programms soll der Rückerstattungsbeitrag bei einer Versicherung berechnet werden. Folgende Rückerstattungssätze seien vereinbart: 0 bis 3 Jahre: 0 % 4 bis 5 Jahre: 10 % mehr als 5 Jahre: 15 % Problemspezifikation: Eingaben : Versicherungsbetrag, Versicherungsdauer Ausgabe : Rückerstattungsbetrag
Programm „Beitrag1“ ... BEGIN { Eingaben } write('Versicherungsbetrag : '); readln(Betrag); write('Versicherungsdauer : '); readln(Dauer); { Berechnungen } IF Dauer <= 3 THEN Erstattung := 0 ELSE IF Dauer <= 5 THEN Erstattung := 0.1 * Betrag ELSE Erstattung := 0.15 * Betrag; { Ausgaben } writeln('Rückerstattung : ', Erstattung:6:2); readln; END.
Zweiseitige Fallunterscheidungen Eingabe: B(etrag), D(auer) D <= 3 wahr falsch D <= 5 wahr falsch E := 0 E := 0.1 * B E := 0.15 * B Ausgabe: E(erstattung) ... IF Dauer <= 3 THEN Erstattung := 0 ELSE IF Dauer <= 5 THEN Erstattung := 0.1 * Betrag ELSE Erstattung := 0.15 * Betrag;
Programm „Beitrag2“ ... BEGIN { Eingaben } write('Versicherungsbetrag : '); readln(Betrag); write('Versicherungsdauer : '); readln(Dauer); { Berechnungen } IF (Dauer >= 0) AND (Dauer <= 3) THEN Erstattung := 0; IF (Dauer = 4) OR (Dauer = 5) THEN Erstattung := 0.1*Betrag; IF Dauer > 5 THEN Erstattung := 0.15 * Betrag; { Ausgaben } writeln('Rückerstattung : ', Erstattung:6:2); readln; END.
Einseitige Fallunterscheidungen Eingabe: B(etrag), D(auer) D >= 0 UND D <= 3 wahr falsch E := 0 D = 4 ODER D = 5 wahr falsch E := 0.1 * B D > 5 wahr falsch E := 0.15 * B Ausgabe: E(erstattung) ... IF (Dauer >= 0) AND (Dauer <= 3) THEN Erstattung := 0; IF (Dauer = 4) OR (Dauer = 5) THEN Erstattung := 0.1*Betrag; IF Dauer > 5 THEN Erstattung := 0.15 * Betrag;
Mehrfachauswahl Eingabe: B(etrag), D(auer) D 0..3 4,5 sonst. E := 0 Ausgabe: E(erstattung) ... CASE Dauer OF 0..3 : Erstattung := 0; 4,5 : Erstattung := 0.1 * Betrag; ELSE Erstattung := 0.15 * Betrag; END;
Einseitige Fallunterscheidung PASCAL Struktogramm PAP IF <Bedingung> THEN <Anweisung> Bed. w f w f Bed. Anw Anw
Zweiseitige Fallunterscheidung PASCAL Struktogramm PAP IF <Bedingung> THEN <Anweisung1> ELSE <Anweisung2> Bed. w f w f Bed. Anw1 Anw2 Anw1 Anw2
Mehrfachauswahl PASCAL Struktogramm Beachte: CASE <Ausdruck> OF <Wert1>: <Anweisung1>; <Wert2>: <Anweisung2>; ... ELSE <Anweisung> END Ausdruck Wert1 Wert2 sonst. Anw1 Anw2 ... Anw Beachte: Der Ausdruck muss „aufzählbare“ Ergebnisse liefern.
Übungen - Aufgabe 9 Problem: Eine Folge nicht-negativer Zahlen soll eingelesen und ihre Summe berechnet und ausgegeben werden. Das Ende der Folge wird durch die Eingabe einer negativen Zahl erkannt. Bsp.: Eingabefolge: 3, 6, 0, 7, -1 Ausgabe: 16 Eingabefolge: -1 Ausgabe: 0 Erstellen Sie einen Algorithmus mit einer WHILE-Schleife und einen Algorithmus mit einer REPEAT-Schleife. Warum kann der Algorithmus nicht mit einer FOR-Schleife erstellt werden? Kontrollieren Sie die Korrektheit der erstellten Algorithmen mit Hilfe einer Trace-Tabelle. Implementieren Sie einen Algorithmus in Pascal und testen Sie seine Korrektheit.
Übungen - Aufgabe 10 A) Worin besteht der Unterschied zwischen den beiden folgenden Anweisungen? IF B1 THEN IF B2 THEN A1 ELSE A2 IF B1 THEN BEGIN IF B2 THEN A1 END ELSE A2 B) Worin besteht der Unterschied zwischen den beiden folgenden Anweisungen? IF B THEN A1; A2 IF B THEN BEGIN A1; A2 END C) Was ist hier falsch? IF B THEN A1; ELSE A2 IF B THEN A1; A2 ELSE A3
Aufgabe 9 - Lösungsvorschlag Summe := 0 Eingabe: z SOLANGE z >= 0 Summe := Summe + z Eingabe: z Ausgabe: Summe Summe := 0 Eingabe: z WENN z >= 0 DANN WIEDERHOLE Summe := Summe + z Eingabe: z BIS z < 0 Ausgabe: Summe
Aufgabe 10 - Lösungsvorschlag A) Worin besteht der Unterschied zwischen den beiden folgenden Anweisungen? IF B1 THEN IF B2 THEN A1 ELSE A2 BEGIN END
Aufgabe 10 - Lösungsvorschlag B) Worin besteht der Unterschied zwischen den beiden folgenden Anweisungen? IF B THEN A1; A2 IF B THEN BEGIN A1; A2 END C) Was ist hier falsch? IF B THEN A1; ELSE A2 IF B THEN A1; A2 ELSE A3 Ende der Anweisung
Teil 6 Datentypen
Siebzehn-und-Vier Ziel ist es, das Spiel „17 und 4“ zu simulieren. Das Spiel soll wie folgt funktionieren: In jedem Spielzug wird eine Karte mit einer Zahl aus dem Bereich [1;...;11] bestimmt und auf einen Kartenstapel gelegt. Der Spieler kann nach jedem Spielzug entscheiden, ob er aufhört oder weiter spielt. Ist die Summe der Zahlen der Karten des Stapels größer als 21, so hat der Spieler verloren. Hört der Spieler bei einer Stapelsumme kleiner oder gleich 21 auf, so wird die nächste Karte gezogen. Ist die neue Stapelsumme immer noch kleiner oder gleich 21, so hat der Spieler verloren, andernfalls gewonnen.
Spielablauf Karte: 8 Karte: 8 Summe: 8 Summe: 8 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): j Karte: 5 Karte: 5 Summe: 13 Summe: 13 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): j Karte: 4 Karte: 4 Summe: 17 Summe: 17 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): n Karte: 6 | 4 Karte: 6 Karte: 3 Summe: 23 | 21 Summe: 23 Summe: 20 Noch eine Karte? (j/n): gewonnen verloren verloren | gewonnen
Ablaufmodellierung WIEDERHOLE Karte ziehen; Summe bestimmen WENN Summe < 21 DANN Ausgabe: ‘ Noch eine Karte? (j/n): ‘ Eingabe: Antwort BIS Summe >= 21 oder Antwort = ‘ n‘ WENN Summe >= 21 DANN WENN Summe > Ausgabe: ‘ verloren ‘ SONST Ausgabe: ‘ gewonnen ‘ SONST Karte ziehen; Summe bestimmen WENN Summe > 21 DANN Ausgabe: ‘ gewonnen ‘ SONST Ausgabe: ‘ verloren ‘
Datenmodellierung Karte: integer (ganze Zahl) Summe: integer (ganze Zahl) Antwort: char (Zeichen) 10 14 ‘n‘
Algorithmus - Version 1, Teil 1 randomize {Initialisierung des Zufallsgenerators} Summe := 0 Karte := random(11)+1 {Zufallszahl aus Bereich 1..11} Summe := Summe + Karte Ausgabe: Karte, Summe Summe < 21 wahr falsch Ausgabe: ‘Noch eine Karte?‘ Eingabe: Antwort BIS (Summe >= 21) OR (Antwort = ‘n‘)
Algorithmus - Version 1, Teil 2 Summe >= 21 wahr falsch Summe > 21 Karte := random(11)+1 Summe := Summe + Karte Ausgabe: Karte, Summe wahr falsch Ausg.: ‘verl.‘ Ausg.: ‘gew.‘ Summe > 21 wahr falsch Ausg.: ‘gew.‘ Ausg.: ‘verl.‘
Spielablauf Karte: 8 Karte: 8 Summe: 8 Summe: 8 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): j Karte: 5 Karte: 5 Summe: 13 Summe: 13 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): j Karte: 4 Karte: 4 Summe: 17 Summe: 17 Noch eine Karte? (j/n): j Noch eine Karte? (j/n): n Karte: 6 | 4 Benutzer hat genug Summe: 23 | 21 Karte: 6 Karte: 3 Noch eine Karte? (j/n): Summe: 23 Summe: 20 Spiel entschieden gewonnen verloren verloren | gewonnen
Datenmodellierung Karte: integer (ganze Zahl) Summe: integer (ganze Zahl) Antwort: char (Zeichen) entschieden: boolean (Wahrheitswert) genug: boolean (Wahrheitswert) 10 14 ‘n‘ true false
Algorithmus - Version 2, Teil 1 randomize {Initialisierung des Zufallsgenerators} Summe := 0 entschieden := false genug := false Karte := random(11)+1 {Zufallszahl aus Bereich 1..11} Summe := Summe + Karte Ausgabe: Karte, Summe Summe >= 21 wahr falsch entschieden := true NOT entschieden wahr falsch Ausgabe: ‘Noch eine Karte?‘ Eingabe: Antwort Antwort = ‘ n‘ w f genug :=true BIS entschieden OR genug
Algorithmus - Version 2, Teil 1 randomize {Initialisierung des Zufallsgenerators} Summe := 0 Karte := random(11)+1 {Zufallszahl aus Bereich 1..11} Summe := Summe + Karte Ausgabe: Karte, Summe entschieden := (Summe >= 21) NOT entschieden wahr falsch Ausgabe: ‘Noch eine Karte?‘ Eingabe: Antwort genug := (Antwort = ‘ n‘) BIS entschieden OR genug
Algorithmus - Version 2, Teil 2 entschieden wahr falsch Summe > 21 Karte := random(11)+1 Summe := Summe + Karte Ausgabe: Karte, Summe wahr falsch Ausg.: ‘verl.‘ Ausg.: ‘gew.‘ Summe > 21 wahr falsch Ausg.: ‘gew.‘ Ausg.: ‘verl.‘
Datentypen Ein Datentyp legt einen Wertebereich und die Grundoperationen, die auf die Elemente des Wertebereichs angewandt werden können, fest. Beispiele (für elementare Datentypen): > boolean (Wahrheitswert) > char (Zeichen) > integer (ganze Zahl) > real (Dezimalzahl)
Datentyp boolean Wertebereich: {false; true} Grundoperationen: NOT, AND, OR a b a AND b false false false false true false true false false true true true a b a OR b false false false false true true true false true true true true a NOT a false true true false
Datentyp char Wertebereich: ... siehe ASCII-Tabelle ... Code Zeichen Code Zeichen Code Zeichen 0 NUL 33 ! 65 A ... ... 66 B 4 EOT 40 ( ... ... ... 90 Z 13 CR 48 0 ... ... 49 1 97 a 27 ESC ... 98 b ... 57 9 ... ... ... 122 z ... ... ...
Datentyp char Grundoperationen: ord, chr, succ, pred, =, >, <, <>, >=, <= (De)Kodieroperationen: ord: char {0; ...; 255} z.B.: ord(´A´) 65 chr: {0; ...; 255} char z.B.: chr(65) ´A´ Ordnungsoperationen: succ: char char z.B.: succ(´A´) ´B´ pred: char char z.B.: pred(´A´) ´@´ Vergleichsoperationen: =: char, char boolean z.B.: ´A´ = ´A´ true >: char, char boolean z.B.: ´A´ > ´B´ false ...
Datentyp integer Wertebereich: -32768; ...; 32767 Grundoperationen: +, -, *, div, mod, succ, pred, =, >, <, ... Divisionsoperationen: div: ganzzahlige Division 20 div 6 = 3 80 div 7 = 11 mod: Rest bei der ganzzahligen Division 20 mod 6 = 2 80 mod 7 = 3
Datentyp real Wertebereich: ..., 1.0; -4.56; 6.3E16; -6.3E-16; ... Grundoperationen: +, -, *, /, =, >, <, ..., round, trunc, sqr, ... Beispiele: round: real integer (Runden) round(3.84) = 4 trunc: real integer (Abschneiden) trunc(3.84) = 3 int: real real (ganzer Teil) int(3.84) = 3.0 frac: real real (Nachkommateil) frac(3.84) = 0.84
Typumwandlung char integer: ord integer char: chr real integer: trunc, round integer real: erfolgt automatisch Bsp.: VAR r: real; r := 3;
Übungen - Aufgabe 11 Miniprojekt Mäusepopulation: Der Algorithmus / das Programm zur Beschreibung der Entwicklung der Mäusepopulation soll wie folgt abgeändert werden: Der Benutzer kann wiederholt die Entwicklung einer Population starten. Er kann dabei jedesmal die Anfangspopulation und die Anzahl der Schritte eingeben und entscheiden, wie die Ergebnisse ausgegeben werden: A) absolute Werte: jung: 34; ... B) prozentuale Werte: Gesamtanzahl: 123; jung: 30%; ... C) grafische Darstellung von Anteilen: Gesamtanzahl: 145 jung: XXXXXX erwachsen: XXXXXXXXXX alt: XXX
Übungen - Aufgabe 12 Miniprojekt Zahlenraten: Der Benutzer soll eine vom Programm vorgegebene Zahl aus dem Intervall [0; 100] mit maximal 8 Rateversuchen ermitteln. Das Programm gibt nach jedem Rateversuch eine passende Rückmeldung. Erweiterungen: A) Führen Sie eine Variable „geraten“ vom Typ boolean ein, mit deren Hilfe das Programm gut lesbar gestaltet werden kann. B) Der Benutzer kann wiederholt das Ratespiel durchführen, ohne das Programm neu starten zu müssen. C) Der Benutzer kann selbst das Intervall, aus dem die zu erratende Zahl stammt, festlegen. Die Anzahl der Rateversuche muss dann natürlich entsprechend angepasst werden.
Hinweise zum algorithmischen Problemlösen Teil 7 Hinweise zum algorithmischen Problemlösen
Ein erstes Phasenschema Spezifikation des Problems Entwicklung eines Algorithmus Implementierung des Algorithmus Validierung des Algorithmus
Spezifikation des Problems Hinweise: Das Problem sollte möglichst genau und eindeutig beschrieben werden. Beschreibungstechniken: AZ: ... Variablenwerte ZZ: ... Variablenwerte; Bildschirmgestaltung Eingaben: ... Ausgaben: ...
Entwicklung eines Algorithmus Hinweise: - sich Klarheit über die zu bearbeitenden und verwendenden Daten verschaffen - sich mögliche Abläufe klar machen (typische Fälle / extreme Fälle) - eine Ablaufbeschreibung mit Hilfe von Kontroll- strukturen konstruieren Entwurfsmethoden: (top-down; bottom-up; objektorientiert; ...)
Implementierung des Algorithmus Hinweise: Programme sollten gut strukturiert sein: - Verschiedene Teile des Algorithmus sollten optisch voneinander abgesetzt werden. - Die Struktur des Algorithmus sollte durch systematisches Einrücken optisch sichtbar gemacht werden. Programme sollten gut lesbar sein: - sinntragende Bezeichner wählen - entscheidenden Stellen kommentieren
Validierung des Algorithmus Hinweise: Validierung während der Erstellung: - Überprüfung mit Trace-Tabellen Validierung nach der Implementierung: - durch systematisches Testen (der Standardfälle, Sonderfälle, ...)
Literaturhinweise Es gibt eine Vielzahl guter Einführungen in die Thematik „Algorithmische Grundstrukturen“. Manche entwickeln die Grundstrukturen ohne Anbindung an eine Programmiersprache, viele verdeutlichen sie parallel an gängigen und aktuellen Sprachen (früher oft Pascal, heute vermehrt Java, Delphi, ...). Einige Beispiele: - Rüdeger Baumann: Informatik für die Sekundarstufe II, Klett-Verlag. - Ocker / Schöttle / Simon: Algorithmen und ihre Programmierung in Pascal. Oldenbourg Verlag. - Laubach / Knoch: Grundkurs Informatik 1 / 2. bsv-Verlag. - Helmut Balzert: Lehrbuch Grundlagen der Informatik. Spektrum-Verlag. - Gumm / Sommer: Einführung in die Informatik. Addison-Wesley.