1_Algorithmus

Werbung
Tipp: Das Online-Buch
http://www.tigerjython.ch
Algorithmus
Ein
Kochrezept,
zum Beispiel:
Kartoffelbrei
Frage:
Aus welchen zwei Teilen
besteht ein Kochrezept ?
Zutaten:
2 Kg Kartoffeln, 0,5 l Milch, 200 gr
Butter, 1 TL Salz, 1 TLPfeffer, 1TL
Muskat
Zubereitung:
Kartoffeln schälen, zerkleinern und in
Salzwasser gar kochen. Mit dem Mörser
zerstampfen und unter Hinzufügen der
Butter und Milch mit dem Schneebesen
schaumig schlagen und würzen.
Ein Algorithmus ist
- salopp ausgedrückt ein
Kochrezept
Präziser:
Ein Algorithmus ist ein
Verfahren zur Lösung
eines gegebenen
Problems. Er hat
folgende Eigenschaften:
• schrittweise
• eindeutig
• endlich
Was "schrittweise" bedeutet, muss in der
konkreten Situation geklärt werden:
Bei einem modernen Rechner bedeutet ein
Schritt z.B:
- Addition zweier Zahlen
- Subtraktion zweier Zahlen
- Multiplikation zweier Zahlen
- Division zweier Zahlen
- Vergleich zweier Zahlen mit <, , <, 
Ein Schritt ist z.B. nicht der Vergleich dreier
Zahlen wie z.B: 3 < 5 < 2
Aufgabe:
Geben Sie ein Beispiel
eines nicht endlichen
"Kochrezepts":
Auf der Suche nach
einer Genehmigung in
irgendeinem Amt:
Der Pförtner schickt Sie
ins Zimmer 10.
Vom Zimmer 10 werden
Sie ins Zimmer 17
geschickt.
Vom Zimmer 17 werden
Sie ins Zimmer 10
geschickt.
10
17
Frage:
Welche Algorithmen
haben Sie bis jetzt in der
Schule kennengelernt ?
-
addieren, subtrahieren
multiplizieren, dividieren,
wurzelziehen
kgV
ggT
Darstellungsmöglichkeiten
eines
Algorithmus
• Flußdiagramm
• Programmiersprache
(z.B. C++)
Elemente des
Flußdiagramms
Anfang bzw. Ende
Anfang
Ende
Eingabe bzw. Ausgabe
Anweisung
Fallunterscheidung
(Verzweigung)
falsch
Bedingung
wahr
kurz:
f
Bedingung
w
Flußrichtung
Variablen
(technisch gesehen sind dies
Stellen im Arbeitsspeicher).
Zum Beispiel wird eine
Eingabe in einer Variablen
gespeichert.
Unter einer Variablen kann man sich
einen Behälter vorstellen.
In diesem Behälter wird ein Wert
gespeichert (z.B. eine bestimmte
Menge Flüssigkeit). Diese Menge
bleibt solange konstant in diesem
Behälter, solange sie nicht verändert
wird. Diese Eigenschaft nennt man
speichern. Es "verdunstet" deshalb
auch nichts.
Jede Variable hat einen Namen, den
der Programmierer vergibt.
Inhalt der
Variablen z1
Inhalt der
Variablen z2
z1
z2
Namen
einer
Variablen
Namen
einer
Variablen
Einer Variablen kann man einen Wert
zuweisen (der Behälter kann gefüllt
werden). Zum Beispiel:
Variablen b wird der Inhalt 0,5 zugewiesen
b := 0,5 Der
(Der Behälter wird mit 0,5 gefüllt).
0,5
b
Das Zeichen := bedeutet soviel wie "der Wert
rechts von := wird der linken Variablen
zugewiesen" und ist auf keinen Fall mit dem
aus der Mathematik bekannten
Gleichheitszeichen = zu verwechseln !
WICHTIG:
Vor dieser Zuweisung hat die Variable b einen
unbekannten Wert. Man sagt, die Variable
hat einen undefinierten Wert.
Einer Variablen kann man einen Wert
zuweisen (der Behälter kann gefüllt
werden). Zum Beispiel:
b := 0,5
0,5
b
Links des Zeichens := muss genau eine Variable
stehen. Rechts davon muss ein Wert oder ein aus
Variablen (und Werten) bestehender Term stehen,
wie z.B. x+y*z oder x * 2
Wichtig:
Umgekehrt gemacht, ist es falsch:
0,5 := b
oder
x + y + z := b
ist falsch.
Was bewirkt die gleich folgende weitere
Anweisung ?
b := 0,5
b := 0,3
0,5
b
Der Variablen b wird der Inhalt 0,3 zugewiesen.
Der alte Wert von 0,5 wird überschrieben und geht
verloren.
Was bewirkt folgende weitere Anweisung ?
b := 0,5
b := 0,3
Der Variablen b wird der Inhalt 0,3 zugewiesen.
Der alte Wert von 0,5 wird überschrieben und geht
verloren.
b
Was bewirkt folgende weitere Anweisung ?
b := 0,5
b := 0,3
0,3
b
Der Variablen b wird der Inhalt 0,3 zugewiesen.
Der alte Wert von 0,5 wird überschrieben und geht
verloren.
Was würde das Gleichheitszeichen =
bewirken ?
b = 0,5
b = 0,3
0,3
b
0,5 = 0,3
Man sieht jetzt auch genau, was passieren
würde, wenn man in der letzten Folie statt := das
Gleichheitszeichen = verwenden würde. Was
würde mathematisch oben aus den zwei
Gebilden folgen ?
Also:
Welche Werte haben die Variablen
g und h ?
g
h
Welche Werte haben die Variablen
g und h ?
?
?
g
h
Was bewirkt folgende Anweisung ?
g := 0,3
?
?
g
h
Was bewirkt folgende Anweisung ?
g := 0,3
?
g
h
Was bewirkt folgende Anweisung ?
g := 0,3
0,3
?
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
0,3
?
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
0,3
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
0,3
0,5
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
g := h
0,3
0,5
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
g := h
0,5
g
h
Was bewirkt folgende weitere Anweisung ?
g := 0,3
h := 0,5
g := h
0,5
g
Der Wert von h - also 0,5 - wird von h in den
Behälter g kopiert (nicht geleert, also nicht
verschieben). Der alte Wert von g wird
überschrieben (er geht verloren, d.h. er wird
vorher gelöscht). D.h. nur der Wert der linken
Variablen wird verändert. Der Wert der rechten
Variablen bleibt unverändert.
Dies entspricht also z.B.
nicht den Erfahrungen eines
durstigen, aber wenig Geld
besitzenden Besuchers einer
Trinkherberge, der in einem
günstigen Augenblick den
Inhalt des benachbarten
Bierglases in den des seinen
verschiebt.
0,5
h
Bitte folgende Regel
einhalten:
Anfangsbuchstabe eines
Variablennamens immer
klein schreiben. Dies ist
dem Compiler zwar egal,
doch an diese Regel halten
sich alle Programmierer.
Aufgabe:
Der Wasserstand des
Neckars wird zweimal im
Jahr (im Sommer und
Winter) gemessen.
Bestimmen Sie den
maximalen Wasserstand,
kurz ...
Bestimmen Sie das
Maximum zweier
eingegebener Zahlen,
wobei ...
... dies durch den Vergleich
zweier Zahlen zu lösen ist.
Auf einmal können nur 2
Zahlen verglichen werden,
also keine 3 oder mehrere.
Also, z.B:
x<y möglich,
x<y<z nicht möglich
Anfang
1. Zahl eingeben:
Eingabe(z1)
2. Zahl eingeben:
Eingabe(z2)
z1 < z2
f
w
max := z2
Das Maximum ausgeben:
Ausgabe(max)
max := z1
Das Zeichen := bedeutet soviel wie
"der Wert der rechten Variablen
wird der linken Variablen
zugewiesen" und ist auf keinen Fall
mit dem aus der Mathematik
bekannten Gleichheitszeichen = zu
verwechseln !
Ende
Nachdem der Algorithmus
entwickelt wurde, muss er
einem “Crash-Test“
(Härte-Test, Stress-Test)
unterzogen werden. Dieses
Prinzip wird prinzipiell in der
Wissenschaft verwendet:
Man versucht eine aufgestellte
Behauptung “kaputt zu
testen“. Anschaulich
gesprochen wird auf die
aufgestellte Behauptung so
lange eingedroschen, bis sie
kaputt geht. Falls dies nicht
gelingt, kann man davon
ausgehen, ein gutes Produkt
entwickelt zu haben.
Wir testen den Algorithmus
für die Eingabe konkreter
Zahlen, wie z.B:
Anfang
1. Zahl eingeben:
Eingabe(z1)
2. Zahl eingeben:
Eingabe(z2)
Annahme (nach der Eingabe),
also an dieser Stelle des
Flußdiagramms:
z1 = 3
z2 = 7
3
7
z1 < z2
7
w
f
7
max := z2
max := z1
7
Das Maximum ausgeben:
Ausgabe(max)
Ende
Welchen Wert hat max
an dieser Stelle des
Flußdiagramms ?
max ist undefiniert, d.h.
der Wert ist unbekannt.
8
Annahme:
z1 = 8
z2 = 2
2
z1 < z2
f
w
max := z2
max := z1
8
Das Maximum ausgeben:
Ausgabe(max)
Ende
8
8
5
Annahme:
z1 = 5
z2 = 5
5
z1 < z2
f
w
max := z2
max := z1
5
Das Maximum ausgeben:
Ausgabe(max)
5
5
Bei allen folgenden Aufgaben
müssen Test-Protokolle gemacht
werden. Bei der Aufgabe das
Maximum zweier Zahlen zu
finden, sieht ein Test-Protokoll z.B.
so aus:
TESTPROTOKOLL
Datum:
25.5.2024
Name des
Erich Überflieger
Entwicklers:
Name des
Ernst Bockelhart
Testers:
TESTDATEN
z1
z2
Algorithmus richtig?
3
7
ja
8
2
ja
5
5
ja
Aufgabe:
Stellen Sie den Algorithmus
durch ein Flußdiagramm dar,
der das Maximum dreier in
beliebiger Reihenfolge
eingegebener Zahlen
berechnet.
Bemerkungen:
1) Nur der wichtigste Teil der
Lösung wird hier und in den
folgenden Lösungen dargestellt
(z.B. wird der Eingabeteil
weggelassen).
2) Im Verzweigungsteil wird w
und f nicht immer angegeben
1. Lösung:
z1 < z2
f
w
max1 := z2
max1 := z1
Zuerst wird - genau so wie ein paar Folien vorher - das Maximum von
den Zahlen z1 und z2 berechnet. Dieses Maximum nennen wir das
vorläufige Maximum (bezeichnet mit max1) , weil es noch nicht das
endgültige Maximum von z1, z2 und z3 ist.
Was muss man jetzt nur noch machen, um das endgültige Maximum zu
berechnen?
Man muss nur noch das Maximum von z3 und max1 berechnen!
z1 < z2
f
w
max1 := z2
max1 < z3
max1 := z1
w
f
max2 := max1
Ausgabe(max2)
Ende
max2 := z3
Vorläufiges Maximum von z1 und z2,
kurz: max1 =Maximum(z1, z2)
Maximum von z3 und max1, also
Maximum von z3 und z1 und z2, kurz:
max2 = Maximum(z3, max1) =
Maximum(z3, z1, z2)
z1 < z2
f
w
max1 := z2
max1 < z3
max1 := z1
w
f
max2 := max1
Ausgabe(max2)
Ende
max2 := z3
Angenommen, man müsste Speicher
sparen. Wie kann man den Algorithmus
mit einer Variable (einem Behälter)
weniger realisieren?
2. Lösung:
10
20
z1 < z2
20
f
20
w
max := z1
max := z2
20
w
max < z3
f
30
max := z3
30
30
30
Ausgabe(max)
Ende
Annahme:
z1 = 10
z2 = 20
z3 = 30
10
20
z1 < z2
20
f
20
w
max := z1
max := z2
20
w
max < z3
f
30
max := z3
Annahme:
z1 = 10
z2 = 20
z3 = 30
30
30
30
Wichtig: max kann also
während des
Programmablaufs
verschiedene Werte
annehmen.
Ausgabe(max)
Berechnet hier das (vorläufige)
Maximum von z1 und z2.
Ende
Berechnet hier das (endgültige) Maximum
von max (also z1 und z2) und z3.
70
60
z1 < z2
f
w
max := z1
max := z2
70
70
70
Annahme:
z1 = 70
z2 = 60
z3 = 50
w
max < z3
max := z3
Ausgabe(max)
Ende
50
f
70
Aufgabe:
Stellen Sie den Algorithmus
durch ein Flußdiagramm dar,
der drei in beliebiger
Reihenfolge eingegebene
Zahlen ihrer Größe nach
aufsteigend sortiert und
ausgibt.
z1 < z2
f
w
z3 < z1
z3 < z2
a:=z3
b:=z1
c:=z2
a:=z3
b:=z2
c:=z1
z3 < z2
a:=z1
b:=z3
c:=z2
Ausgabe(a,b,c)
a:=z1
b:=z2
c:=z3
z3 < z1
a:=z2
b:=z3
c:=z1
a:=z2
b:=z1
c:=z3
Aufgabe:
Stellen Sie den Algorithmus durch ein Flußdiagramm dar, der
für eine Klassenarbeit für jeden Schüler den Prozentsatz
erreichter Punkte – auf die maximal möglich zu erreichende
Gesamtpunktzahl bezogen - errechnet und ausgibt.
a) Die Klasse besteht aus 1 Schüler.
b) Die Klasse besteht aus „unendlich“ vielen Schülern.
c) Die Klasse besteht aus 50 Schülern.
d) Der Lehrer kann die Schüleranzahl eingeben.
Lösung a)
Anfang
Eingabe (gesamtpunkte)
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
Ende
Lösung b)
Anfang
Eingabe (gesamtpunkte)
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
Ende
Was muss man machen,
damit nochmals das gleiche
für mehrere Schüler gemacht
wird ?
Man muss ein Schleife
einbauen !
Anfang
Eingabe (gesamtpunkte)
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
Warum ist dies ein
anwenderunfreundliche
Lösung ?
Weil der Anwender bei
jedem Schüler die
Gesamtpunkte nochmals
eingeben muss, obwohl
diese Zahl für jeden Schüler
die gleiche ist.
Welche Lösung wäre dann
anwenderfreundlicher ?
Anfang
Eingabe (gesamtpunkte)
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
Lösung c):
(für 50 Schüler)
Eingabe (gesamtpunkte)
Was muß in diese Lösung
noch eingebaut werden,
damit genau 50 Schüler
ausgegeben werden ?
Eingabe (punkte)
Ein Zähler und eine
Verzweigung, die den Wert
des Zählers überprüft.
Anfang
p := punkte/gesamtpunkte*100
Ausgabe(p)
Eingabe(gesamtpunkte)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler < 50
f
Ende
PROBLEM:
Woher kann man sicher sein,
dass in der Verzweigung die
Bedingung zähler < 50
heißt ?
Warum könnte hier z.B.
nicht stehen:
zähler < 51 oder
zähler  51
Im folgenden wird eine
Möglichkeit dargestellt, wie
man nachprüfen kann, ob
das Programm das
Gewünschte macht.
Welcher Zusammenhang besteht
Eingabe(gesamtpunkte)
zwischen Schülerausgaben und zähler ?
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
Am roten Pfeil wird das
Programm bei jedem
Durchgang gedanklich
angehalten und der Wert der
Variablen zähler und die
Anzahl der Schülerausgaben
protokolliert (besonders der
erste und der letzte
Durchgang): Dieses
schrittweise Abarbeiten des
Programms nennt man auch
"Schreibtischtest"
zähler
zähler := zähler + 1
w
1
2
zähler < 50
f
Schülerausgaben = zähler ...
letzter Durchgang: 50
Ende
Schülerausgaben
1
2
...
50
Was muß im Programm
geändert werden, damit die
Schüleranzahl eingegeben
werden kann ?
Eingabe(gesamtpunkte)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler <
f
Ende
Eingabe(gesamtpunkte)
Eingabe(anz)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler < anz
f
Ende
Eingabe(gesamtpunkte)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler < 50
f
Ende
NOCHMALS PROBLEM:
Woher kann man sicher sein,
dass in der Verzweigung die
Bedingung zähler < 50
heißt ?
Warum könnte hier z.B.
nicht stehen:
zähler < 51 oder
zähler  51
Im folgenden wird eine
weitere Möglichkeit
dargestellt, wie man
nachprüfen kann, ob das
Programm das Gewünschte
macht.
Eingabe(gesamtpunkte)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler < 50
f
Ende
Da es sehr aufwendig wäre,
das ganze Programm (der
Wert 50 ist sehr groß) bis
zum Programmende am
Schreibtisch durch zu gehen,
nimmt statt 50 einfach einen
kleinern Wert, wie z.B. 3
und führt das Programm bis
zum Programmende am
Schreibtisch durch.
Außerdem muss natürlich
ein Protokoll gemacht
werden. Nach jedem Schritt
des Programms wird der
Wert der Variablen neben
die Variable geschrieben
Eingabe(gesamtpunkte)
zähler := 0
Eingabe (punkte)
p := punkte/gesamtpunkte*100
Ausgabe(p)
zähler := zähler + 1
w
zähler <
f
Ende
Da es sehr aufwendig wäre,
das ganze Programm (der
Wert 50 ist sehr groß) bis
zum Programmende am
Schreibtisch durch zu gehen,
nimmt statt 50 einfach einen
kleinern Wert, wie z.B. 3
und führt das Programm bis
zum Programmende am
Schreibtisch durch.
Außerdem muss natürlich
ein Protokoll gemacht
werden. Nach jedem Schritt
des Programms wird der
Wert der Variablen neben
die Variable geschrieben
200
Eingabe(gesamtpunkte)
0
zähler := 0
20 30 50
Eingabe (punkte)
10 15 25
p := punkte/gesamtpunkte*100
10 15 25
Ausgabe(p)
1 2 3
zähler := zähler + 1
1 2 3
zähler < 3
f
Ende
w
Da
es nehmen
sehr aufwendig
Wir
an, dasswäre,
hier
das ganze Programm (der
wird.
Wert200
50eingegeben
ist sehr groß)
bis
zum Programmende am
Wir nehmendurch
an, dass
hier
Schreibtisch
zu gehen,
20 statt
eingegeben
wird.
nimmt
50 einfach
einen
kleinern Wert, wie z.B. 3
Wirführt
nehmen
an, dass hier
und
das Programm
bis
eingegeben wird.
zum30
Programmende
am
Schreibtisch durch.
Wir nehmen
an,natürlich
dass hier
Außerdem
muss
50 eingegeben
wird.
ein Protokoll
gemacht
werden. Nach jedem Schritt
des Programms wird der
Wert der Variablen neben
die Variable geschrieben
200
Eingabe(gesamtpunkte)
0
zähler := 0
20 30 50
Eingabe (punkte)
10 15 25
p := punkte/gesamtpunkte*100
10 15 25
Ausgabe(p)
1 2 3
zähler := zähler + 1
1 2 3
zähler < 3
f
Ende
w
Da esEssehr
aufwendig
wäre,
wurden
also bei
das ganze Programm (der
zaehler
< 3 bis
Wert 50 ist
sehr groß)
Ausgaben gemacht.
zum3Programmende
am
Schreibtisch durch zu gehen,
Also statt
ist es50"einsichtig",
nimmt
einfach einen
kleinern Wert,
dass wie
bei z.B. 3
und führt
das Programm
bis
zaehler
< 50
zum Programmende am
50 Ausgaben
gemacht
Schreibtisch
durch.
Außerdemwerden.
muss natürlich
ein Protokoll gemacht
werden. Nach jedem Schritt
des Programms wird der
Wert der Variablen neben
die Variable geschrieben
Aufgabe:
Siehe Übungsblatt
Die 2. Möglichkeit, einen
Algorithmus zu
beschreiben ist die
Programmiersprache.
Eine Programmiersprache ist eine
künstliche Sprache – im Gegensatz zu
einer natürlichen Sprache (wie z.B. der
englischen Sprache).
Eine künstliche Sprache wird für
spezielle Dinge - wie z.B. der
Programmierung - benutzt, weil eine
natürliche Sprache dazu zu ungenau
wäre.
Programmiersprache:
• Syntax
• Semantik
Die Syntax definiert die äußeren
Formgesetze dieser
Programmiersprache (ähnlich den
grammatikalischen Regeln einer
natürlichen - wie z.B. der englischenSprache).
Die Semantik ist der Bedeutungsinhalt
(ähnlich der Bedeutung der einzelnen
Worte einer natürlichen - wie z.B. der
italienischen - Sprache) der einzelnen
Objekte einer Programmiersprache.
Eine "höhere" Programmiersprache (z.B:
Java, C, Pascal, Cobol, Pascal, Prolog,
usw.) kann zwar von einem Menschen
verstanden werden ("menschengerecht"),
doch nicht von einem Mikroprozessor
(dem Herz des Computers), weil ein
Mikroprozessor nur sogenannte
Maschinenbefehle (bestehen aus 0 en und
1 en) versteht.
Deshalb benötigt man einen Übersetzer
(engl. Compiler), der einen in einer
höheren Programmiersprache
formulierten Text (ein sogenanntes
Programm) in einen aus
Maschinenbefehlen bestehenden Text
(einem sogenannten
Maschinenprogramm) verwandelt. Dieses
kann dann vom Mikroprozessor
abgearbeitet (ausgeführt) werden.
Herunterladen