All_2004_06_24 - Benutzer-Homepage

Werbung
Grundlagen der
Informatik
Prof. Dr. Peter Kneisel
Zum Kennenlernen







Wie alt sind Sie ?
Aus welchen (Bundes-)Ländern kommen Sie ?
Wo wohnen Sie während des Studiums ?
Welchen Bildungsweg sind Sie gegangen ?
Wer hatte Informatik in der Schule ?
Welches Fach studieren Sie ?
Warum studieren Sie hier an der FH Gießen ?






Wer besitzt einen Computer ?
Wie lange sitzen Sie vor dem Computer ?
Was machen Sie da ?
Welche Programmiersprache können Sie ?
Welche Betriebssysteme (OSe) kennen Sie ?
Welche Anwendungen kennen Sie ?
 Was erwarten Sie (nicht) von dieser Vorlesung ?
 Was denken Sie, mit dieser Vorlesung anfangen zu können ?
Didaktik: Durchführung
 Diese Vorlesung ist formal 3-stündig mit einer Stunde Übungen
 Die Übungen werden in diesem Verhältnis, aber nur je nach Bedarf
durchgeführt.
 Zur Vorbereitung werden Übungsblätter, je nach Vorlesungsverlauf
zusammengestellt. Weitere Übungen sind im Foliensatz vorhanden und
sollten selbständig und vollständig bearbeitet werden.
 Der Vorlesungsstoff ist an die Struktur und Inhalten der GDI-Vorlesung
von Dr. Geisse angelehnt.
 Zur Vor- und Nachbereitung des Stoffes können Sie daher zusätzlich
dessen Vorlesungsmitschrift (erhältlich in der Fachschaft) verwenden
 Da sich die Inhalte und insbesondere auch Schwerpunkte leicht
verschieben ist dennoch ein Arbeiten mit meinem Foliensatz erforderlich
 Vorsicht !
 Kommen Sie in alle Veranstaltungen - machen Sie die Übungen
 überschätzen Sie sich nicht - auch wenn Sie PC-Crack sind
 Schreiben Sie die Klausur nur, wenn Sie eine Chance haben
( Ich hasse es, Zeit mit dem Korrigieren hoffnungsloser Fälle zu vergeuden ;-)
Didaktik: Folien
 Der Vorlesungsstoff wird anhand von Folien dargelegt
 Die Folien bilden nur einen Rahmen für die Inhalte. Die Folien sollten daher
mit Hilfe eigener Vorlesungsskizzen ergänzt werden - am besten in Form
einer Vorlesungsnachbereitung max. 3 Tage nach der Vorlesung
 Zusätzlich zu den Folien werden Beispiele an der Tafel oder am Rechner
gezeigt. Diese sollten Sie vollständig mitskizzieren.
 Zur vollständigen Nachbereitung, z.B. als Klausurvorbereitung, sind die
Folien einheitlich strukturiert
 Es gibt genau drei Gliederungsebenen: Kapitel, Unterkapitel, Abschnitte
 Die Inhalte jedes Kapitels und jedes Unterkapitels werden jeweils motiviert
und sind verbal beschrieben. Zusätzlich gibt es jeweils ein stichwortartiges
Inhaltsverzeichnis der Unterkapitel, bzw. Abschnitte
 Die Vorlesung wird ständig überarbeitet, so dass sich die Foliensätze
ändern können (und werden)
 Laden Sie sich zur endgültigen vollständigen Nachbereitung nochmals
zusätzlich den kompletten Foliensatz herunter.
Literatur
 Diese Veranstaltung ist anhand (wirklich) vieler Bücher und einer Menge
eigener Erfahrungen erstellt worden. Jedes Buch hat dabei
Schwerpunkte in speziellen Bereichen und ist daher sinnvoll. Eine
Auflistung aller dieser Bücher ist nicht sinnvoll.
 An dieser Stelle seien daher nur drei Bücher aufgeführt, die einen guten
Einstieg in die Informatik darstellen.
(Diese Liste ist identisch mit der von Dr.Geisse erstellten Liste)
 Ch. Horn, I.O. Kerner, P.Forlig
Lehr- und Arbeitsbuch - Informatik, Band 1 Grundlagen und Überblick
Fachbuchverlag Leibzig 2001
 P. Reichenberg
Was ist Informatik - Eine allgemeinverständliche Einführung
Hanser Verlag München 1991
 Fl. Bauer, G. Goos
Informatik - eine einführende Übersicht Band 1+2
Springer Verlag Berlin 19991/92
Inhalt
 Wie jede Wissenschaft befasst sich die Informatik mit ihren eigenen
„Objekten“. Was diese „Objekte“ sind und was man mit diesen Objekten
machen kann - und wie - wird in dieser Vorlesung auf eher abstraktem
Niveau, aber immer mit Beispielen aus der Realität eines Informatikers
(oder einer Informatikerin), erläutert.
 Diese Vorlesung konzentriert sich auf den „Kern“ der Informatik. Vertieftere
Einführungen in z.B die Bereiche der Programmierung,
Rechnerarchitekturen, Betriebssysteme, etc. sollen daher bewusst den
entsprechenden Veranstaltungen vorbehalten bleiben
 Inhalt
1.
2.
3.
4.
5.
6.
7.
Informatik
Information und Codes
Zeichen und Zahlen
Datenstrukturen
Algorithmenentwurf
Algorithmentheorie
Sprachen
Überblick und Einordnung
CB
RA2
Typ2-Sprachen
7
Typ3-Sprachen
Syntax und Semantik
Komplexität
Korrektheit
6
Berechenbarkeit
Strukturierung
Elemente
Praktische
1
5
Statik (Struktur)
Prg1
Dynamik (Algorithmik)
Sprachen
Prg2 SWT1 DSt
Datenstrukturen
4
Zeichen
3
Zahlen
Codes
Information
Theoretische
Informatik
RA1
2
Technische
Kapitel 1
Informatik
 1962 wurde der Begriff „Informatique“(als Kombination der Begriffe
„Information“ und „automatique“) von Philippe Dreyfus, einem
französischen Ingenieur eingeführt und als „Informatik“ ins Deutsche
übernommen. Als junge Wissenschaft ist die Informatik mittlerweile in
viele Bereiche der älteren Wissenschaften eingezogen und hat viele
eigene Bereiche neu erschlossen. Die Informatik ist damit mittlerweile
wesentlich mehr, als der anglo-amerikanische Begriff „ComputerScience“ vermuten lässt.
Dieses Kapitel möchte einen (kurzen) Überblick über exemplarische
Inhalte, Struktur und Geschichte der Informatik geben
 Inhalt
1.
2.
3.
4.
5.
Motivation
Definition
Die Teilgebiete der Informatik
Die Geschichte der Informatik
Zusammenfassung des Kapitels
1.1
Motivation
 Die Beherrschung eines Computers macht Spaß und gibt der
informationssüchtigen Gesellschaft das Gefühl persönlicher Freiheit (so
wie vor Jahren ein roter Sportwagen)
 Die Beherrschung gibt Macht. Für das Funktionieren einer
demokratischen Gesellschaft ist es wichtig, daß viele Menschen
Computer verstehen und beherrschen.
 Der Computer schafft und vernichtet Arbeitsplätze und ist eine
Herausforderung für die Gesellschaft
 Das Verstehen der Gesetzmäßigkeiten bei der Entwicklung von
Computerprogrammen ist eine intellektuelle Herausforderung
 Das Umsetzen dieses Verständnisses ist eine intellektuelle
Genugtuung.
 Der Computer schafft neue Betätigungsfelder und Lebensinhalte
 Der professionelle Umgang mit Computer ist im Beruftsleben eine
nackte Notwendigkeit !
1.2
Was ist Informatik
 Jedes Lehrbuch der Informatik gibt seine Definition der „Informatik“.
Auch der Duden beschreibt die Informatik als „Wissenschaft von der
systematischen Verarbeitung von Informationen, besonders der
automatischen Verarbeitung mit Hilfe von Digitalrechnern“.
Durch die Beschränkung auf den Aspekt der „Verarbeitung“ geht diese
Definition meines Erachtens nicht weit genug. Ich werde daher in
diesem Unterkapitel eine eigene Definition wagen. Die dabei
verwendeten Aspekte werden exemplarisch verdeutlicht, wobei
bewusst in Grenzbereiche der Informatik gegangen wird .
 Was die Informatik wirklich ist, kann kein Lehrbuch erfassen.
Sie werden - hoffentlich - am Ende Ihres Studiums eine sehr
weitreichende Idee davon haben.
 Inhalt
1. Definition
2. Beispiele
1.2.1 Definition
Informatik
Die Wissenschaft, die sich mit dem
(automatisierten)
Erfassen
Transportieren
Speichern
Verarbeiten
Umsetzen
von Information befasst
1.2.2 Wissenschaft
 Informatik ist nicht die Wissenschaft vom Computer
(sowenig, wie Astronomie die Wissenschaft vom Teleskop ist)
 Informatik ist eine Wissenschaft
… und keine Bastelecke für Software-Spieler
 Aspekte der Informatik als
 „reine Lehre“ (verwandt mit der Mathematik)
 Naturwissenschaft: entdecken und beschreiben von „natürlichen“
Phänomenen
 Ingenieurwissenschaft - mit der typischen Vorgehensweise





Problemstellung
Analyse
Teillösungen
Synthese
Lösung
1.2.3 Information
 Information ist die Bedeutung, die durch eine Nachricht übermittelt wird
(nachrichtentechnische Definition)
  Kapitel 2
 Information ist eine elementare Kategorie
 Chemie: Stoffumwandlung
 Physik: Energieumwandlung
 Informatik: Informationsumwandlung
1.2.4 Erfassen
Sensorik
 Bildverarbeitung
Datenmenge
(Byte)
300000
60000
3000
(52,204,248)
(33,75,125,190,251)
100
1.2.5 Transportieren
Telekommunikation
 Telephonie
~5-25000 Hz
300 - 3400 Hz
1.2.6 Speichern
Datenrepräsentation
 Abstrakte Datentypen (N. Wirth: Algorithmen und Datenstrukturen)
Einfache Typen
Strukturierte Typen
Abstrakte Typen
Aufzählungstypen
Integer
Real
Boolean
Char
...
Array
Record
Varianten Record
Menge
...
Listen
Binäre Bäume
Vielweg Bäume
Graphen
...
{rot, gelb, grün}
array [n..m] of Type
[0,1,..,65535]
record
Type 1: element 1
Type n: element n
end
[3,4e-038,..3,4e038]
{TRUE, FALSE}
{ASC(0),..,ASC(255)}
set of Type
1.2.6 Speichern
Datenrepräsentation
 Objektrepräsentation
(G. Booch: Objektorientierte Analyse und Design)
Assoziation
Klassenname
Vererbung
Attribute
Operationen
Einschränkungen
Aggregation
Verwendung
Instantiierung
Mitarbeiter
Projekt
Buchhaltung
n
Controlling
1
Projektleiter
Teil
projekt
Personalwesen
1.2.6 Speichern
 Objektrepräsentation
Projekt
Mitarbeiter
n
Projektleiter
Datenrepräsentation
(B.Stroustrup: The C++ Programming Language)
Buchhaltung
Controlling
Teilprojekt
1
Personalwesen
Assoziation
Vererbung
Aggregation
Verwendung
Instantiierung
Class Teilprojekt: public Projekt {
Projektleiter projektleiter;
Mitarbeiter
mitarbeiter[MAX_MITARBEITER];
public:
Teilprojekt (Projektleiter);
~Teilprojekt ();
}
Teilprojekt::Teilprojekt(Projektleiter pl) {
// some method-calls of Buchhaltung, Controlling, Personalwesen
}
main {
Teilprojekt1 = new Teilprojekt(Projektleiter1)
// See Budget1 for buget details on Teilprojekt1
}
1
n
1.2.7 Verarbeiten
 Petri-Netze
Prozessmodelle
(C.A.Petri: Kommunikation und Automaten))
1.2.7 Verarbeiten
Prozessmodelle
 Interaktionsdiagramme
(G. Booch: Objektorientierte Analyse und Design)
R1
R2
R3
R4
N2
R5
N1
1.2.7 Verarbeiten
KI-Ansätze
a
W
O
F
f
 Neuronale Netze
Oj
Axon
Wij
Synapsen
Dendrite
Aktivierungszustand
Verbindungsgewichtung
Ausgangswert
Aktivierungsfunktion
Ausgabefunktion
ai=F(Wij*Oj ,ai)
Oi=f(ai)
1.2.8 Umsetzen
Aktorik
 Manipulatoren
Anzahl Freiheitsgrade
25
9
2 (1)
1.2.9 Zusammenfassung





Reduktion von Redundanz
Strukturierung von Information
Abbildung realer Prozesse auf Rechnerprozesse
Abbildung von Rechnerprozessen auf reale Prozesse
Abbildung von Datenstrukturen auf reale Strukturen
1.3
Die Teilgebiete der Informatik
 Wie viele Wissenschaften, ist die Informatik kein homogenes Gebilde,
sondern lässt sich anhand unterschiedlicher Kriterien in Teilgebiete
strukturieren.
Dieses Kapitel beschreibt die wohl geläufigste Einteilung der Informatik
in drei, bzw. vier Teilbereiche.
 Inhalte
1.
2.
3.
4.
Technische Informatk
Praktische Informatik
Theoretische Informatik
( Angewandte Informatik )
1.3.1 Technische Informatik
 Konstruktion von Verarbeitungselementen
 Prozessoren, ...
 Konstruktion von Speicherelementen
 Hauptspeicher, ...
 Konstruktion von Kommunikationselementen
 Bussysteme
 Lokale Rechnernetze (LAN: Local Area Networks), Weitverkehrsnetze
(WAN: Wide Area Networks), ...
 Mobilfunknetze, Satellitenkommunikation, ...
 Konstruktion von Peripherie
 Drucker, Scanner, ....
 Festplatten, Optische Platten, Diskettenlaufwerke, ...
 ...
1.3.2 Praktische Informatik
 Umgang mit Programmiersprachen
 Compilerbau
 ...
 Entwicklung von Software





Analysemethoden
Designmethoden
Realisieruingsmethoden
Testverfahren
...
 Unterstützung der Softwareentwicklung
 Projektmanagment von DV-Projekten
 Qualitätsmanagement in DV-Projekten
 ...
 ...
1.3.3 Theoretische Informatik
 Sprachen und Automaten
 Formale Sprachen
 Grammatiken
 Sprachdefinitionen
 Berechenbarkeitstheorie
 Komplexitätstheorie
 ...
1.3.4 Angewandte Informatik
 Anwendung in verwandten Wissenschaften






Numerische oder stochastischer Verfahren in der Mathematik
Simulationen in der Physik und der Chemie
Bildverarbeitung in der Medizin
Genanalyse in der Biologie
Lehrprogramme für Natur-, Sozial- und Geisteswissenschaften
...
 Anwendungen im täglichen Leben.





 ...
Computerspiele, Multimediaanwendungen,
Textverarbeitung, Tabellenkalkulation, Datenbanken, ...
Steuerung von technischen Prozessen
Web-Anwendungen
...
1.4
Die Geschichte der Informatik
 Die Informatik ist eine junge Wissenschaft, hat aber, ähnlich wie andere
Natur- und Ingenieurwissenschaften Wurzeln, die weit in die
Menschheitsgeschichte hineinragen, Wie keine andere Wissenschaft
wurde die Informatik jedoch von der Erfindung eines Gerätes, dem
programmgesteuerten Rechner (später „Computer“) beeinflusst.
Dieses Unterkapitel wird die Wurzel in der Menschheitsgeschichte und
auch die Entwicklung des Rechners vorstellen.
 Inhalt
1.
2.
3.
4.
5.
6.
Information in der Geschichte
Automaten und Steuerungen
Erleichterung der Rechenarbeit
Pioniere der Informatik - Praktiker
Pioniere der Informatik - Theoretiker
Die Generationen
1.4.1 Information in der Geschichte





Erfassung durch Sinnesorgane
Transport durch akustische, optische, chemische Signale
Speicherung durch Gene oder neuronale Elemente
Verarbeitung über neuronale Elemente
Umsetzung direkt oder indirekt über Gliedmaße
 Entwicklung von Wort,- Silben- und Buchstaben-schriften
1.4.2 Automaten und Steuerungen
 ca. 100 n. Chr.
Automatische Tempeltore in Anhängigkeit von Opferfeuer (Heron von
Alexandria)
 Mittelalter
Mechanische Uhren mit Sonnen-, Mond- und Planetenbewegungen und
Figurenumläufe an Kirchen und Rathäusern
 17./18. Jhdt.
Spieluhren, Schreib- und Schachspielautomaten
 18./19. Jhdt.
Fliehkraftregler für Dampfmaschinen, mechanischer Webstuhl mit
Lochkartenbändert (Jacquart, 1805)
1.4.3 Erleichterung der Rechenarbeit
 Rechenbretter
 Seit dem Altertum
 China, Japan, Rußland
 Addition/Subtraktion ähnlich schnell wie
Taschenrechner
 Lehre der Grundrechenarten
 Durch Zahlensystem schematisierbar
 Lehre an mittelalterlichen Universitäten
 Durch Rechenbücher weitere Verbreitung des
Wissens (z.B. Adam Riese 1492-1559)
 Rückführung der Multiplikation/Division auf
Addition/Subtraktion durch logarithmisches
Rechnen mit Hilfe von Tabellen.
1.4.4 Mechanische Rechenmaschinen
 Wilhelm Schickart (1592-1635)
 Maschine für die Grundrechenarten
(1623)
 Blaise Pascal (1623-1662)
 Gottfried Wilhelm von Leibniz (1646-1716)
 Arithmetik des Dualsystems
 Philipp Matthäus Hahn (1749-1790)
 Feinmechanische Rechenmaschinen
 19./20. Jhdt: Sprossenradmaschine
 Hermann Hollerith
 Lochkartenstanzer/
-sortierer/-tabellierer
1.4.5 Pioniere der Informatik - Praktiker
 Charles Babbage (1791-1871)
 Difference Engine (1812). Überprüfung von
Logarithmentafeln. Alle Merkmale eines programmierbaren
Computers.
 Entwurf einer Analytical Engine (1836).
Wurde nie gebaut
 Konrad Zuse (geb. 1910)
 Z1: mechanischer Rechner
 Z2 / Z3: Elektromechanischer Relaisrechner im
Dualsystem mit Lochkartensteuerung.
Erster voll funktionstüchtiger Computer (1941)
 Grundlegende Arbeiten zur Programmierung und
algorithmischer Sprachen
 Howard Eiken
 Mark I, II, III, IV (1944)
Dezimalrechnender Relaisrechner
1.4.6 Pioniere der Informatik - Theoretiker
 Kurt Gödel
 Theoretische Aussagen zum Algorithmenbegriff:
Es gibt Aussagen die algorithmisch nicht entscheidbar sind
(1931)
 Alan M. Turing (1911-1954)
 Definition des Algorithmenbegriffes über eine hypothetische
Maschine
(Turing-Maschine)
 John von Neumann (1903-1957)
 Grundlegende Arbeiten über Computerarchitektur:
 Speicherung der Daten und Programme auf dem gleichen
Medium
 Definition von Registern insb. Indexregister
1.4.7 Die Generationen
Generation
Vorgenerat.
1941-1944
1.Generation
1946 - 1958
2. Generation
1959 - 1964
3. Generation
1965 - 1980
4. Generation
1999
Gegenwart
5. Generation
Beispiel
Z3
Mark1
ENIAC, Z22
UNIVAC, IBM650
SIEMENS704
IBM1400, AEG TR
CDC6600
Siemens2002
IBM370, PDP11
Siemens7000,
Cray 1
PC, Gray XMP
Sperry1100, VAX
IBM309x
Workstations
HochleistungsNetze
Technologie
Elektromechanik
Elektroröhren
Speich./Geschw.
0,0002 MIPS
Software
Verdrahtet
0,02 MIPS
1-2 Kbyte
Maschinensprache
Transistoren
Kernspeicher
0,1 MIPS
32 KByte
ICs
Halbleiterspeicher
Mikroprozessoren
Optische Sp.
Pentium,
Power PC
5 MIPS
1-2 Mbytes
Assembler
FORTRAN
Stapelbetrieb
Hochsprachen
C, Pascal
50 MIPS
8-32 MByte
100 MIPS
1 GByte
C++. JAVA
supraleitende 1000 MIPS
Keramiken
viele GBytes
Sprachen der 19814. Generation
Parallelisierung
Netzsoftware
OO-Sprachen PCs
1.5

Zusammenfassung des Kapitels
Die Informatik befasst sich mit der (automatisierten)
Erfassung, dem Transport, der Speicherung, Verarbeitung und dem
Umsetzen von Information
 Die Informatik ist eine „naturwissenschaftliche Ingenieurswissenschaft“
 Die Informatik gliedert sich in Technische, Praktische, Theoretische und
Angewandte Informatik
 Die Geschichte der Informatik beginnt im Altertum, besteht in Ihrer
heutigen Form aber erst seit ca 1945. Zur Zeit befinden wir uns in der 4.
Generation.
Kapitel 2
Information und Codes
 Information ist der grundlegende Begriff in der Informatik - dieses
Kapitel erläutert diesen Begriff:
Zunächst wird Information in ihrer Repräsentation als „Nachricht“
betrachtet und damit einige Maßzahlen definiert. Danach wird auf die
Repräsentation von Information in der Informatik und deren Maßzahlen
eingegangen. Schließlich wird auf die Möglichkeiten zur Umsetzung Kodierung - von Information eingegangen
 Inhalt
1.
2.
3.
4.
Was ist Information
Definition nach Shannon
Definition in der Informatik
Codes
2.1
Was ist Information
 Information ist eine elementare Kategorie
 wie z.B. Energie oder „Stoff“
Nicht:
Was ist Information ?
sondern: Wie ist Information ?
 Qualitativ: Repräsentationsformen der Information







DNS (Aminosäuren in einem Doppelhelix)
Verschaltung von Neuronen und deren Empfindlichkeit
physikalisches Objekt (Atome im Raum)
Bild (Bildpunkte auf einer Ebene)
Energieverteilung (Energie im Raum)
Folge von Zeichen (Zeichen in einer Zeichenkette)
.....
 Quantitativ: Maßzahlen für Information
  später in diesem Kapitel
2.2
Definition nach Shannon
 Information hat vielfältige Repräsentationsformen. Noch vor Entstehen
der Informatik als Wissenschaft hat Claude Elwood Shannon (19162001) wichtige Maßzahlen zur Erfassung von Information definiert.
Dabei geht er von der nachrichtentechnischen Repräsentation von
Information, der „Nachricht“ aus.
Dieses Unterkapitel stellt diese Maßzahlen und deren Grundlagen dar.
 Inhalt:
1.
2.
3.
4.
Nachricht
Informationsgehalt einer Nachricht
Informationsgehalt eines Zeichens
Mittlerer Informationsgehalt
2.2.1 Definition: Nachricht
 sei Alphabet X: Menge von Symbolen/Zeichen X = {x1, x2, ... xn}
 Eine Zeichenkette (ein Wort) der Länge n über X ist eine Folge von n
Zeichen aus X (ein n-Tupel über X)
 Beispiel: X={a,b}
Worte über X:
Worte der Länge n mit n=3:
{a,b,ab,ba,aba,abb,baa,bbb, ...}
{aba,abb,baa,bbb}
 Die Menge aller n-Tupel über X ist das n-fache
Kreuzprodukt X  X  ...  X (n mal), bezeichnet als Xn
 |Xn| = | X  X  ...  X | = |X| * |X| * ... * |X| = |X|n
 Die Anzahl der Elemente alle Worte mit der maximalen Länge n ist |X|n
 Wird eine Zeichenkette übermittelt, so spricht man von Nachricht Nx
2.2.2 Definition: Informationsgehalt einer Nachricht
 Ein Maß für die Information (der Informationsgehalt) einer Nachricht
Nn,x der Länge n (über ein Alphabet X) ist die Länge der Beschreibung,
die notwendig ist, um die Nachricht Nn,x aus der Menge aller möglichen
Nachrichten der Länge n zu ermitteln
 Beispiel:
 Information der Nachricht N8,{0,1} : Suche in |{0,1}|8 = 256 Wörtern
obere Hälfte ?
ja
nein
obere Hälfte ?
obere Hälfte ?
ja
nein ja
nein
Optimal mit binärem Suchen
Anzahl Fragen:
ld(|Xn|) = ld(|X|n) = n ld(|X|)
...
 Der Informationsgehalt einer aus mehreren (voneinander
unabhängigen) Zeichen bestehenden Zeichenkette ist gleich der
Summe der Informationen der einzelnen Zeichen:
 1 * ld(|X|) + 1* ld(|X|) + ... + 1* ld(|X|) = n * ld(|X|) = ld(|X|n)
2.2.3 Definition: Informationsgehalt eines Zeichens
 Idee:
 Der Informationsgehalt eines Symbols xi hängt von der Wahrscheinlichkeit
seines Auftretens ab: Je seltener ein Symbol auftritt, desto höher ist sein
Informationsgehalt:
h(xi) = f(1/p(xi))
 Definition nach Shannon (ca. 1950):
Der Informationsgehalt h (Einheit bit) eines Symbols xi ist definiert als
der Logarithmus dualis des Reziprokwertes der Wahrscheinlichkeit, mit
der das Symbol auftritt:
h(xi) = ld(1/p(xi)) = -ld p(xi)
2.2.4 Beispiel: Informationsgehalt
 Beispiel: Sei die Wahrscheinlichkeit von E = 0,5 und die von H = 0,25
 Informationsgehalt des Zeichens „E“ :
hE = ld (1/0.5) = 1
 Informationsgehalt des Zeichens „H“ :
hH = ld (1/0,25) = 2
 Informationsgehalt der Zeichenkette „EHE“
hEHE = ld(2) + ld(4) + ld(2) = ld(2 * 4 * 2) = 4 bit
Umrechnungsregel des ld in den 10er-Logarithmus (lg)
log a b =
log c b
log c a
lg b
mit a = 2, c = 10 gilt: ld b =
lg 2
 3,322 lg b
2.2.5 Definition: Mittlerer Informationsgehalt
 Kennt man die Einzelwahrscheinlichkeiten aller möglichen Symbole
einer Symbolsequenz, so ist der mittlere Informationsgehalt Hs der
Symbole s (Entropie der Quelle) definiert als:
Hs =  p(xi) * h(xi) =  p(xi) * ld(1/p(xi)) = -  p(xi) * ld(p(xi))
 Der mittlere Informationsgehalt Hs,n einer Symbolkette der Länge n ist:
Hs,n = Hs * n
 Beispiel
x
y
z
P
0,5
0,25
0,25
x
y
z
p
0,5
0,25
0,25
h
1
2
2
Hs = 0,5 * 1 + 0,25 * 2 + 0,25 * 2 = 1,5 bit
d.h. die Symbole haben
einen mittleren Informationsgehalt von 1,5 bit.
2.2.6 Informationsaufnahme des Menschen
 Beim Lesen erreicht der Mensch eine Geschwindigkeit von ca. 25
Zeichen/sec
 das entspricht 25 * 2 Bit (mittleren Informationsgehalt) = 50 Bit/sec
 dieser Wert ist unabhängig vom Alphabet - kann also auch z.B. im
chinesischen erreicht werden.
 Nachrichten, die mit anderen Medien dargestellt werden, können ca.
genauso schnell verarbeitet werden.
 Aufnahme des Menschen
 Bewusst aufgenommen werden ca. 50% von 50 Bit/sec also 25 bit/sec
 Bei einer Aufnahmedauer von ca. 16 Stunden am Tag ergibt sich eine
Lebensinformationsmenge von ca. 3 * 1010 Bit
 die Speicherkapazität des Gehirns ist mit ca. 1012 Bit auch in der Lage,
diese Informationsmenge zu speichern (sogar 100 Mal)
 Die Lebensinformationsmenge findet auf einer CD-ROM Platz und ist über
Glasfaserkabel in wenigen Sekunden zu übertragen.
2.3
Definition in der Informatik
 Die Wurzeln der Informatik liegen weniger in der Nachrichtentechnik, als
vielmehr in der Mathematik. Darum ist die Repräsemtation von
Information als Nachricht weniger relevant als die Darstellung von
Zahlen (in binärer Repräsentation) und algebraischen (bool‘schen)
Objekten.
In diesem Unterkapitel geht es um diese Repräsentationen.
 Inhalt
1.
2.
3.
4.
Das Bit in der Informatik
Die Darstellung des Bit
Beispiel
Das Byte und mehr
2.3.1 Das Bit in der Informatik
 Definition aus der Informatik:
Ein Bit ist die Informationsmenge in einer Antwort, auf eine Frage, die
zwei Möglichkieten zuläßt:




ja /nein
wahr/falsch
schwarz/weiß
...
 Der Informationsgehalt eines Zeichens einer zweielementigen
Alphabetes mit gleicher Auftretungswahrscheinlichkeit ist
(nach Shannon)
h = -ld p = -ld 0,5 = 1
2.3.2 Die Darstellung des Bit
 Diese zwei Möglichkeiten werden meist mit 0 bzw. 1 codiert
 Die technische Darstellung erfolgt u.a. mit Hilfe von:
 Ladung
 0 = ungeladen
 1 = geladen
 Spannung
 0 = 0 Volt
 1 = 5 Volt
 Magnetisierung
 0 = nicht magnetisiert
 1 = magnetisiert
 Licht
 0 = kein Licht
 1 = Licht
2.3.3 Beispiel: Bitfolge
 Aus welcher Himmelsrichtung weht der Wind (N, O, S, W) ?
 Bei anzunehmender Gleichverteilung der Antworten ist der mittlere
Informationsgehalt H =  p(xi) * ld(1/p(xi)) = (0,25*2)*4 = 2
 Die Frage läßt sich in zwei Fragen umsetzen
 Weht der Wind aus N oder O (ja/nein) ?
 Weht der Wind aus O oder W (ja/nein) ?
 Eine mögliche Antwort: 1 Frage=ja, 2 Frage=nein läßt sich durch die
Bitfolge 10 darstellen und bezeichnet eindeutig Norden als die
Windrichtung




10 = Norden
11 = Osten
01 = Westen
00 = Süden
 Nimmt man noch die Zwischenrichtungen NO, SO, SW und NW hinzu, so
können die 8 Zustände mit 3 Bit codiert werden (wie?)
2.3.4 Das Byte und mehr
 Aus bestimmten Gründen
 Geschwindigkeit von Lese- und Schreiboperationen
 Darstellungsmöglichkeit „häufiger“ Zeichen (z.B. Alphabet)
 Darstellungsmöglichkeiten von Zahlen, etc.
werden in der Informatik oft Vielfache von 8Bit-Gruppen verwendet
(8Bit, 16Bit, ...)
Eine 8-Bitsequenz heißt ein Byte.
 Bestimmte 2er-Potenzen werden in der Informatik häufig als Maßzahlen
(z.B. für Speichergrößen) verwendet:




1 kByte = 210 = 1024 Byte (1 Kilobyte)
1 Mbyte = 210 * 210 Byte (1 Megabyte)
1 Gbyte = 210 * 210 * 210 Byte (1 Gigabyte)
1 Tbyte = 210 * 210 * 210 * 210 Byte (1 Terabyte)
2.4
Codes
 Damit Information in einem Rechner verarbeitet werden kann, muss
sie in eine für den Rechner verarbeitbare Form transformiert werden.
Dabei kann man sich beliebig ungeschickt anstellen.
Dieses Unterkapitel beschreibt, wie eine solche Transformation
funktionieren kann, welche Möglichkeiten man dabei hat und gibt ein
Maß für die Qualität einer Transformation an.
 Inhalt
1.
2.
3.
4.
5.
Was ist ein Code
Willkürliche Codes
Codes zur Optimierung der Codelänge
Codes zur Fehlererkennung und –korrektur
Redundanz
2.4.1 Was ist ein Code
 Definition:
Seien X,Y zwei Alphabete
 Eine Codierung ist eine Abbildung C:XnYm aller n-Tupel aus X nach mTupel aus Y.
 oft ist n=1
 oft ist Y = {0,1}
 Die Worte aus Ym werden Code genannt.
 Die Umkehrrelation C-1 bezeichnet man als Dekodierung
 Definition:
Ein Code heißt vollständig, wenn alle Wörter aus Xn mit Hilfe des
Codes abgebildet werden können.
 Definirion:
Ein Code heißt eindeutig, wenn der Code aller Wörter aus Xn
unterschiedlich ist, ansonsten heiß er mehrdeutig
2.4.2 Willkürliche Codes
 Codes sollten so beschaffen sein, dass sie bei der Decodierung
eindeutig sind.
 Beispiel:
z
p
h
h*p
c
l
l*p
A
0,2
5,00
2,32
101
3
0,60
E
0,3
3,33
1,74
01
2
0,60
I
0,2
5,00
2,32
100
3
0,60
O
0,25
4,00
2,00
11
2
0,50
U
0,05
20,00
4,32
11100 5
0,25
R=L-H=0,38
H = 2,17
L = 2,55
 Problem Dekodierung:
 10111100100
=
101 11100 100
101 11 100 100
(aui)
(aoil)
2.4.2 Willkürliche Codes: Fano-Bedingung
 Kein Codewort darf Anfang eines anderen Codewortes sein
 Beispiel:
z
c
z
c
A
101
A
00
E
01
E
10
I
100
I
010
O
11
O
11
U
11100
U
011
 Die Fano-Bedingung ist hinreichend aber nicht notwendig
 Beispiel: a  1, b  10
2.4.3 Huffman-Codierung
 Oft ist es wichtig, einen Code möglichst kurz zu gestalten
 Idee
 Häufige Symbole – kurze Codes, Seltene Symbole – lange Codes
 Kodierung
 Die Häufigkeit des Auftretens der Bitmuster (Bytes) wird bestimmt
 Die am häufigsten auftretenden Bytes werden mit kurzen Bitfolgen
(Huffmann-kode) kodiert
 Der Huffmann-code wird zur Kodierung der Bitfolge verwendet
 Dekodierung
 Dekodierer besitzt identischen Huffmann-kode (oder bekommt die
Zuordnungstabelle explizit übertragen)
 Dekodierer setzt den Huffmann-code in Bytefolge um
2.4.3 Huffman-Codierung: Vorgehen
 Der Baum wird von oben nach unten mit den zwei Buchstaben (oder
Buchstabengruppen) mit den jeweils kleinsten Wahrscheinlichkeiten
schrittweise aufgebaut
sei
P(A) = 0,16
P(B) = 0,51
P(C) = 0,09
P(D) = 0,13
P(E) = 0,11
P(C)=0,09
P(E)=0,11
1
0
P(D)=0,13
1
P(CE)=0,2
1
0
P(AD)=0,29
1
P(B)=0,51
P(A)=0,16
0
P(CEAD)=0,49
0
P(BCEAD)=1,0
Kodierung
A = 000
B=1
C = 011
D = 001
E = 010
2.4.3 Huffman-Codierung: Verbesserung
 Codierung ist optimal, wenn sich die Wahrscheinlichkeiten der Zeichen
„geschickt“ ergeben
 „geschickt“ sind Wahrscheinlichkeiten mit negativen 2er-Potenzen.
 Durch Betrachtung (und Codierung) von Zeichenpaaren, -drillingen, ... ,
n-Tupeln können solche „geschickten“ Wahrscheinlichkeiten gefunden
werden
 Die Redundanzen lassen sich sogar beliebig verkleinern, weil die
Einzelwahrscheinlichkeiten von n-Tupeln beliebig klein werden und
dadurch immer „geschickter“ kombiniert werden können
 Beispiel:
z
p
z
p
z
p
A
0,80
AA
0,64
AAA
0,512
B
0,20
AB
0,16
AAB
0,032
BA
0,16
ABA
0,128
BB
0,04
...
...
BBB
0,008
Produkt der Einzelwahrscheinlichkeiten
...
2.4.3 Huffman-Codierung: Beispiel
 Beispiel
z
p
h
h*p
c
l
l*p
A
0,80
0,32
0,26
0
1
0,80
B
0,20
2,32
0,46
1
1
0,20
R = 0,26
H = 0,72
z
p
h
h*p
c
l
l*p
AA
0,64
1,56
0,41
0
1
0,64
AB
0,16
6,25
0,42
10
2
0,32
BA
0,16
6,25
0,42
110
3
0,48
BB
0,04
25,00
0,19
111
3
0,12
R = 0,12
H = 1,44
L = 1,00
L = 1,56
2.4.4 Hamming-Codierung
 Manchmal ist es wichtig, Fehler in einem Code zu erkennen und ggf. zu
korrigieren. (z.B. bei der Übertragung)
 Idee
 Gezielter Einsatz von Redundanz
 Nicht alle möglichen Codeworte sind daher gültig
 Kodierung
 Dem Code werden zusätzliche Bits hinzugefügt.
 Die Werte der zusätzlichen Bits szehen in Bezug zu den ursprünglichen
Bits
 Beispiel aus der natürlichen Sprache
 “Ich studiere in Gießer” – Fehler kann erkannt und behoben werden
 “Ich liebe rich” – Fehler kann erkannt, aber nicht behoben werden
2.4.4 Hamming-Codierung: Beispiel ASCII
 Paritätsbit bei der 7-bit ASCII-Codierung
 wähle das 8te Bit so, dass immer eine gerade Anzahl von Bits gesetzt ist
(gerade Anzahl = „even parity“, ungerade Anzahl = „odd parity“)
Zeichen
@
A
B
C
Binär
100 0000
100 0001
100 0010
100 0011
mit even Parity
1100 0000
0100 0001
0100 0010
1100 0011
 erhält man eine Nachricht mit ungerader Anzahl, so weiß man, dass
(mindestens) ein Bit verkehrt ist.
 man weiß allerdings nicht welches
 man weiß auch nicht, ob nicht mehr als ein Bit verkehrt ist
 man weiß bei richtigem parity-Bit auch nicht, ob nicht mehr als 1 Bit
verkehrt ist
 Idee: den „Abstand“ gültiger Worte so groß wie nötig wählen
2.4.4 Hamming-Codierung: Hamming-Distanz
 Definition:
Der Hamming-Abstand (die Hamming-Distanz D) zwischen zwei
Wörtern ist die Anzahl der Stellen, an denen sich zwei Worte gleicher
Länge unterscheiden.
 Beispiel: Hamming-Abstand von 1100 0000 (A) und 0100 0001 (B) = 2
 Definition:
Der Hamming-Abstand (die Hamming-Distanz D) eines Codes ist
der minimale Hamming-Abstand zwischen zwei beliebigen Wörtern
des Codes.
 Beispiel: Hamming-Abstand von ASCII (mit even parity) = 2
 Einige Konzequenzen:
 Codes mit Hamming-Distanz = 0 sind nicht eindeutig
 Bei Codes mit Hamming-Distanz = 1 kann das „Kippen“ eines Bits zu
einem anderen gültigen Codewort führen (muss nicht)
 Bei Codes mit Hamming-Distanz = 2 kann ein Ein-Bit Fehler erkannt
werden.
2.4.5 Hamming-Codierung: Fehlererkennung
 Fehler, bei denen höchstens D-1 Bits gestört sind, können sicher
erkannt werden
 einige andere Fehler können, müssen aber nicht erkannt werden
(genau dann, wenn die Hamming-Distanz zwischen zwei Wörtern eines
Codes größer als die Distanz des Codes ist)
 Fehler werden erkannt, wenn ein Codewort ungültig ist
gültiges Codewort
erkennbares Codewort
A
korrigierbares Codewort
B
1-Bit-Fehler
2-Bit-Fehler
2.4.5 Hamming-Codierung: Fehlerkorrektur
 Fehler, bei denen höchsten (D-1)/2 Bits gestört sind, können sicher
korrigiert werden
 einige andere Fehler können, müssen aber nicht korrigiert werden können
(genau dann, wenn die Hamming-Distanz zwischen zwei Wörtern eines
Codes größer als die Distanz des Codes ist)
 Falsches Codewort wird em „nächstmöglichen“ Codewort (d.h. dem mit
der minimalen Distanz) zugeordnet.
gültiges Codewort
erkennbares Codewort
A
B
korrigierbares Codewort
1-Bit-Fehler
2-Bit-Fehler
2.4.5 Hamming-Codierung: Hamming
 Idee
 Jedes Prüfbit stellt die gerade Parität einer gewissen Menge von Bits
(einschließlich sich selbst) sicher
 Jedes Datenbit kann in mehreren dieser Mengen einbezogen sein
 Die Hamming-Methode
... P D D D P D P P
8
1
 Es werden an der 1,2,4,8,... Stelle Prüfbits eingeführt
 Jedes Prüfbit hat damit in seiner dualen Stellennummer genau eine Stelle
mit einer 1 (1,2,4,8,... = 1,10,100,1000,...)
 Alle Stellen im Wort, die an derselben Stelle eine 1 haben (und an den
anderen 1 oder 0) werden aufsummiert
 1  001,011,101,111, ...
also 1,3,5,7, ... Stellen
 10  010,011,110,111, ... also 2,3,6,7, ... Stellen
 100  100,101,110,111, ... also 4,5,6,7, ... Stellen
 Das entsprechende Parity-Bit wird als even-parity Bit gesetzt
2.4.5 Hamming-Codierung: Beispiel Hamming
 zu kodieren: 1011
 Prüfbit 1 (001)
relevant 011,101,111
also Bit 3,5,7
Summe = 3  Bit setzen
 Prüfbit 2 (010)
relevant 011,110,111
also Bit 3,6,7
Summe = 2  Bit löschen
 Prüfbit 4 (100)
relevant 101,110,111
also Bit 5,6,7
Summe = 2  Bit löschen
 kodiert: 1010101
1 0 1 P 1 P P
7
1
1 0 1 P 1 P 1
1 0 1 P 1 0 1
1 0 1 0 1 0 1
2.4.5 Hamming-Codierung: Beispiel Hamming
 Fehlerhafter Code: 1000101
 Verfahren
1 0 0 0 1 0 1
7
1
 prüfe alle Parity-Bits
 k = Summe der fehlerhaften
Bitnummern
 k gibt die Nummer des gestörten
Bits an (nur bei 1-Bit Fehler
zuverlässig)
 Hier:





Bit1 prüft 3,5,7: falsch
Bit2 prüft 3,6,7: ok
Bit4 prüft 5,6,7: falsch
k=1+4=5
 Bit5 muss getauscht werden
1 0 1 0 1 0 1
2.4.6 Genetische Codierung
 Beim Menschen ist die Desoxyribonukleinsäure (DNS, engl. DNA) der
Träger der genetischen Information und Hauptbestandteil der
Chromosomen.
 Die DNS ist ein kettenförmiges Polymer aus Nukleotiden, die sich in ihren
Stickstoffbasen unterscheiden (Thymin/Cytosin bzw. Adenin/Guanin,)
 das Alphabet des Codes ist also:
{Thymin, Cytosin, Adenin, Guanin,} oder auch { T, C, A, G }
 Je drei aufeinanderfolgende Basen bilden ein Wort
 Es gibt also 43 = 64 Kombination
 die Wortlänge ist also ld(64) Bit = 8 Bit




Ein Gen enthält etwa 200 Worte
Ein Chromosom enthält ca. 104 bis 105 Gene
Die Anzahl der Chromosomen pro Zellkern ist beim Menschen 46
Die pro Zellkern gespeicherten Daten haben damit ein Volumen von
8 Bit * 200 * 105 * 46 = 73600 Bit * 105  104 MBit  1 GByte
2.4.6 Definition: Mittlere Wortlänge
 Codiert man die Zeichen eines Alphabetes binär (also mit Sequenzen
eines 2-Zeichen-Alphabetes, z.B. 0 und 1) , so versteht man unter der
mittleren Wortlänge L eines Codes die mit den
Auftrittswahrscheinlichkeiten gewichtete Summe der Längen l(xi) der
den einzelnen Symbole entsprechenden Codewörtern
L =  p(xi) * l(xi)
 Beispiel
x
y
z
Code
1
01
00
l
1
2
2
p
0,5
0.25
0,25
h
1
2
2
p*h
0,5
0,5
0,5
p*l
0,5
0,5
0,5
011100011
yxxzyx
H = 1,5 Bit
L = 1,5 Bit
2.4.6 Definition: Redundanz
 Die mittlere Wortlänge eines Binärcodes ist immer größer oder gleich
dem mittleren Informationsgehalt.
 Die Differenz zwischen mittlerer Wortlänge und mittlerem
Informationsgehalt wird als Redundanz R des Codes bezeichnet:
R=L-H
 Die Redundanz bezogen auf die Wortlänge nennt man relative
Redundanz r:
r=R/L
 Redundanz ist also ein Maß für die Qualität einer Kodierung (insofern
die Länge eines Codes als Qualität angesehen wird)
2.5.6 Redundanz – Beispiel
 Beispiel
x
y
z
Code
1
01
00
l
1
2
2
p
0,5
0.25
0,25
h
1
2
2
p*h
0,5
0,5
0,5
p*l
0,5
0,5
0,5
p
0,7
0.2
0,1
h
0,515
2,322
3,322
p*h
0,360
0,464
0,332
011100011
H = 1,5 Bit
H = 1,156 Bit
yxxzyx
L = 1,5 Bit
L = 1,3 Bit
H =  pi * hi = -  pi * ld(pi)
= 0,360+0,464+0,332 = 1,156
L =  pi * li
= 0,7+0,4+0,2 = 1,3
R =L-H
= 1,3 - 1,156 = 0,144
r =R/L
= 0,144 / 1,3 = 0,111
p*l
0,7
0,4
0,2
2.5
Zusammenfassung des Kapitels
 Was ist Information
 Definition nach Shannon
 Informationsgehalt
 eines Zeichens (x)
 einer Nachricht (n)
h(x) = ld (1/p(x)) = - ld (p(x)
h(n) = h(n1) + h(n2) + h(n3) + ...
 Mittlerer Informationsgehalt
 eines Zeichens (x)
 einer Nachricht (n)
H(x) =  p(xi) * h(xi)
|n| * H(x)
 Definition in der Informatik
 Bits und Bytes
 Codes
 Codes
 mittlere Wortlänge
 Huffman
 Hamming
 Redundanz
L =  p(xi) * l(xi)
R=L-H
Achtung:
Nicht
verwechseln !
Kapitel 3
Zeichen und Zahlen
 Auch wenn Objekte der realen Welt beliebig komplex in Zusammensetzung uns Struktur sind, so werden sie in den meist auf zwei einfache
Repräsentationen - als Abstraktion - abgebildet:
Zeichen und Zahlen.
Dieses Kapitel beschreibt, wie diese Objekte in eine für den Rechner
verarbeitbare Form kodiert werden können.
 Inhalt
1. Kodierung von Zeichen
2. Darstellung von Zahlen
3.1
Kodierung von Zeichen
 Die Wurzeln der Informatik liegen in der Mathematik. Die ersten
„Computer“ waren Rechner im wörtlichen Sinne, deren Aufgabe die
Verarbeitung von Zahlen war. Mittlerweile hat sich der Aufgabenschwerpunkt in Richtung „Elektronischer Datenverarbeitung“ verschoben, wobei als Datum immer weniger Zahlen im Mittelpunkt stehen,
als vielmehr Texte.
Dieses Unterkapitel beschreibt verschiedene Möglichkeiten die „Atome“
eines Textes, die Buchstaben, zu kodieren.
 Inhalt
 ASCII
 EBCDIC
 UNICODE
3.1.1 ASCII -Tabelle (7Bit)
 American Standard Code for Information Interchange
@ NUL 000 T
DC4 020 (
040 <
060 P
080 d
100 x
120
A
SOH 001 U
NAK 021 )
041 =
061 Q
081 e
101 y
121
B
STX 002 V
SYN 022 *
042 >
062 R
082 f
102 z
122
C
ETX 003 W
ETB 023 +
043 ?
063 S
083 g
103 {
123
D
EOT 004 X
CAN 024 ,
044 @
064 T
084 h
104 _|
124
E
ENQ 005 Y
EM
025 -
045 A
065 U
085 i
105 }
125
F
ACK 006 Z
SUB 026 .
046 B
066 V
086 j
106 ~
126
G
BEL
007 [
ESC 027 /
047 C
067 W
087 k
107
H
BS
008 \
FS
028 0
048 D
068 X
088 l
108
I
HT
009 ]
GS
029 1
049 E
069 Y
089 m
109
J
LF
010 ^
RS
030 2
050 F
070 Z
090 n
110
K
VT
011 _
US
031 3
051 G
071 [
091 o
111
L
FF
012 SP
032 4
052 H
072 \
092 p
112
M
CR
013 !
033 5
053 I
073 ]
093 q
113
N
SO
014 "
034 6
054 J
074 ^
094 r
114
O
SI
015 #
035 7
055 K
075 _
095 s
115
P
DLE 016 $
036 8
056 L
076 `
096 t
116
Q
DC1 017 %
037 9
057 M
077 a
097 u
117
R
DC2 018 &
038 :
058 N
078 b
098 v
118
S
DC3 019 '
039 ;
059 O
079 c
099 w
119
DEL
127
3.1.1 ASCII - Sonderzeichen
 Bedeutung der Sonderzeichen im ASCII-Code
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
DLE
DC1
Null, or all zeros
StartHeading
StartText
EndText
EndTransmission
Enquiry
Acknowledge
Bell
Backspace
HorizontalTab
LineFeed
VerticalTab
FormFeed
CarriageReturn
ShiftOut
ShiftIn
DataLinkEscape
DeviceControl1(XON)
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
DC2
DC3
DC4
NAK
SYM
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
SP
DeviceControl2
DeviceControl3(XOFF)
DeviceControl4
Neg.Acknowledge
SynchronousIdle
EndTrans.Block
Cancel
EndofMedium
Substitute
Escape
FileSeparator
GroupSeparator
RecordSeparator
UnitSeparator
Space
?
DEL
Delete
3.1.2 EBCDIC - Tabelle
 Extended Binary Coded Decimals Interchange Code
nul
soh
stx
etx
pf
ht
lc
del
ge
rlf
smm
vt
ff
cr
so
si
dle
dc1
dc2
tm
res
nl
bs
il
can
em
00
001
002
003
004
005
006
007
008
009
00a
00b
00c
00d
00e
00f
010
011
012
013
014
015
016
017
018
019
cc
cu1
ifs
igs
irs
ius
ds
sos
fs
01a
01b
01c
01d
01e
01f
020
021
022
023
byp 024
lf
025
etb 026
esc 027
028
029
sm
02a
cu2 02b
02c
enq 02d
ack 2e
bel
2f
030
031
syn 032
033
pn
rs
uc
eot
cu3
dc4
nak
sub
Sp
¢
.
>
(
034
035
036
037
038
039
03a
03b
03c
03d
03e
03f
040
041
042
043
044
045
046
047
048
049
04a
04b
04c
04d
+
|
&
!
$
*
)
;
/
04e
04f
050
051
052
053
054
055
056
057
058
059
05a
05b
05c
5d
5e
5f
060
061
062
063
064
065
066
067
068
069
| 06a
, 06b
% 06c
06d
< 06e
? 06f
070
071
072
073
074
075
076
077
078
` 079
: 07a
# 07b
@ 07c
' 07d
= 07e
" 07f
080
a 081
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
082
083
084
085
086
087
088
089
08a
08b
08c
08d
08e
08f
090
091
092
093
094
095
096
097
098
099
09a
09b
~
s
t
u
v
w
x
y
z
09c
09d
09e
09f
0a0
0a1
0a2
0a3
0a4
0a5
0a6
0a7
0a8
0a9
0aa
0ab
0ac
0ad
0ae
0af
0b0
0b1
0b2
0b3
0b4
0b5
{
A
B
C
D
E
F
G
H
I
0b6
0b7
0b8
0b9
0ba
0bb
0bc
0bd
0be
0bf
0c0
0c1
0c2
0c3
0c4
0c5
0c6
0c7
0c8
0c9
0ca
0cb
0cc
0cd
0ce
0cf
}
J
K
L
M
N
O
P
Q
R
0d0
0d1
0d2
0d3
0d4
0d5
0d6
0d7
0d8
0d9
0da
0db
0dc
0dd
0de
0df
\ 0e0
0e1
S 0e2
T 0e3
U 0e4
V 0e5
W 0e6
X 0e7
Y 0e8
Z 0e9
0ea
0eb
0ec
0ed
0ee
0eF
0 0f0
1 0f1
2 0f2
3 0f3
4 0f4
5 0f5
6 0f6
7 0f7
8 0f8
9 0f9
| 0fa
0fb
0fc
0fd
0fe
eo 0ff
3.1.2 EBCDIC - Sonderzeichen
 Die Bedeutung der Sonderzeichen
Char
Description
Char
Description
Char
Description
ACK
Acknowledge
EOT
End of Transmission
PN
Punch On
BEL
Bell
ESC
Escape
RES
Restore
BS
Backspace
ETB
End of Transmission Block
RS
Reader Stop
BYP
Bypass
ETX
End of Text
SI
Shift in
CAN
Cancel
FF
Form Feed
SM
Set Mode
CC
Cursor Control
FS
Field Separator
SMM
Start of Manual Message
CR
Carriage Return
HT
Horizontal Tab
SO
Shift Out
CU1
Customer Use 1
IFS
Interchange File Separator
SOH
Start of Heading
CU2
Customer Use 2
IGS
Interchange Group Separator
SOS
Start of Significance
CU3
Customer Use 3
IL
Idle
SP
Space
DC1
Device Control 1
IRS
Interchange Record Separator
STX
Start of Text
DC2
Device Control 2
IUS
Interchange Unit Separator
SUB
Substitute
DC4
Device Control 4
LC
Lower Case
SYN
Synchronous Idle
DEL
Delete
LF
Line Feed
TM
Tape Mark
DLE
Data Link Escape
NAK
Negative Acknowledge
UC
Upper Case
DS
Digit Select
NL
New Line
VT
Vertical Tab
EM
End of Medium
NUL
Null
ENQ
Enquiry
PF
Punch Off
3.1.3 Unicode
 Aktuelle Version 4.0.0 (siehe auch www.unicode.org)
 Buchstaben und Symbole aus allen wichtigen geschriebenen
Sprachen der Welt




Amerika, Europa, Mittlerer Osten, Afrika, Indien, Asien, Pazifik
Symbole
Satzzeichen
Sonderzeichen
 Wird genormt in ISO/IEC 10646
 Kompatibilität mit ASCII
 0000 - 007F: identisch mit 7-bit ASCII
 007F - 00FF: Latin-1 Supplement (nationale Sonderbuchstaben)
 2500 - 25FF: Blockgraphikzeichen (Box Drawing: ╘╚╞╬└┴├...)
3.1.3 Unicode: Beispiele
 05F1
 FA0E
 2603
 20AC
 xxD0 - xxDF
3.2
Darstellung von Zahlen
 Die Darstellung von Zahlen spielt in der Informatik nach wie vor eine
wichtige Rolle. Dabei gibt es unterschiedliche Mengen von Zahlen und
auch unterschiedliche Operationen auf Zahlen.
Dieses Unterkapitel beschreibt die Grundlagen der Zahlenkodierung,
gibt für alle Mengen von Zahlen eine konkrete Kodierung an und führt in
die Computerarithmetik ein.
 Inhalt
1.
2.
3.
4.
5.
6.
7.
8.
Zahlensysteme
Konvertierung
Arithmetik
Ganze positive Zahlen
Ganze negative Zahlen
Gebrochene Zahlen
Gleitpunktzahlen
Standards
3.2.1 Zahlensysteme
 Nicht systematische Zahlendarstellungen, z.B.:
 Strichliste: I, II, III, IIII, IIII, IIII I, ...
 römische Zahlen: MIM, IX, ....
 Systematische Zahlendarstellungen in einem Stellenwertsystem
 Jede Zahl N läßt sich als Sequenz von Zeichen a i darstellen
 Die Anzahl der notwendigen unterscheidbaren Zeichen ist B
 N=ai* Bi
 Im Dezimalsystem ist B = 10 und die unterscheidbaren Zeichen sind:
0,1,2,3,4,5,6,7,8,9
 Im Binärsystem ist B = 2 und die unterscheidbaren Zeichen sind: 0,1
3.2.1 Zahlensysteme - Beispiele
 Dezimalsystem:
 199910 = 1*103 + 9*102 + 9*101 + 9*100
 Binärsysten:
 199910 = 1*210+1*29+1*28+1*27+1*26+1*23+1*22+1*21+1*20
111110011112
 Hexadezimalsystem (Sedezimalsystem)
 Zeichen: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
 199910 = 7*162 + 11*161 + 15*160 = 7BF16 = 0x07BF = H‘07BF
 4 Zeichen einer Binärzahl lassen sich durch eine Hexadezimal-ziffer
darstellen (4 Binärziffern nennt man auch NIBBLE)
 Oktalsystem
 Zeichen: 0,1,2,3,4,5,6,7
 199910 = 3*83 + 7*82 + 1*81 + 7*80 = 37178
 3 Zeichen einer Binärzahl lassen sich durch eine Oktalziffer darstellen
3.2.2 Konvertierung: „Intuitivmethode“
 Addition von geigneten Zweierpotenzen (Dezimalzahl  Dualzahl)
 positive Zweierpotenzen für Vorkommaanteil
 negative Zweierpotenzen für Nachkommaanteil
 Vorgehen (getrennt nach Vor- und Nachkommateil)
 Suche größte Zweierpotenz, die noch in die Zahl passt
 Subtrahiere die Zweipotenz von der Zahl
daraus ergibt sich die neue Zahl für die Suche der Zweierpotenz
 Dieses Vorgehen terminiert ...
 ... beim Vorkommateil: wenn die Zahl = 0
 ... beim Nachkommateil: wenn die Zahl erreicht ist, vielleicht nie
 Beispiel:
39
7
3
1
100111
25 39 - 32 = 7
22
7-4 =3
21
3-2 =1
20
1-1 =0
0,8125
0,3125
0,0625
0,1101
2-1 0,8125 - 0,5
= 0,3125
2-2 0,3125 - 0,25
= 0,0625
2-4 0,0625 - 0,0625 = 0
3.2.2 Konvertierung: Restwertmethode
 Erzeugen des Hornerschemas (Ausklammern der Basis b)
c0 = anbn + an-1bn-1 + ... + a2b2 +a1b1 + a0b0 
c0 = (( ... (anb + an-1) b + ... + a2) b +a1) b + a0 
c0 / b = c1 Rest a0 , mit c0= ( ... (anb + an-1) b + ... + a2) b +a1 ,
c1 / b = c2 Rest a1 , mit c1= ... (anb + an-1) b + ... + a2 ,
...
cn / b = 0 Rest an ( terminiert mit cn+1 = 0 )
 Konversion der Nachkommastellen (folgt aus Hornerschema):
1. Multiplikation mit Basis (bis ganzzahliges Ergebnis oder gewünschte Genauigkeit)
2. Abspalten der Vorkommastelle des Ergebnisses, weiter mit 1.
 Beispiel
19 : 2 =
9:2=
4:2=
2:2=
1:2=
9
4
2
1
0
Rest 1
Rest 1
Rest 0
Rest 0
Rest 1
0,6875 * 2 =
0,375 * 2 =
0,75 * 2 =
0,5 * 2 =
1,375
0,75
1,5
1
0,1011
10011
1 abspalten
0 abspalten
1 abspalten
1 abspalten
3.2.2 Arithmetik
 Addition
 Subtraktion
 Multiplikation
 Division
0
0
1
1
+
+
+
+
0
1
0
1
=
=
=
=
0
1
1
0 Übertrag 1
1011
+ 1110
0
0
1
1
-
0
1
0
1
=
=
=
=
0
1 Übertrag 1
1
0
1101
- 1010
0
0
1
1
*
*
*
*
0
1
0
1
=
=
=
=
0
0
0
1
1101 * 11
1101
+ 1101
100111 : 11 = 01101
100
-11
0011
-11
0011
-11
00
111
Überträge
11001
1
Überträge
0011
1 1
100111
Überträge
3.2.3 Ganze positive Zahlen
 Positive ganze Zahlen werden meist direkt in ihrer binären Darstellung
kodiert.
 Die BCD (Binäry Coded Digits) - Darstellung von Zahlen ist eine
Mischform aus Dezimal- und Binärdarstellung:




Jede Ziffer der Dezimalzahl wird binär dargestellt.
Die Darstellung jeder Ziffer erfolgt mit 4 Bits.
Die Reihenfolge der Ziffern bleibt erhalten.
Beispiele:




7
0111
53 0101 0011
1234 0001 0010 0011 0100
1999 0001 1001 1001 1001
0
1
2
3
4
5
6
7
8
9
Pseudotetraden
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
3.2.4 Ganze negative Zahlen: Probleme
 Darstellung des Vorzeichens im ersten Bit, z.B.
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 0
1001 = -1
1010 = -2
1011 = -3
1100 = -4
1101 = -5
1110 = -6
1111 = -7
 Nachteil durch Redundanz der Darstellung der 0
 Nachteil durch Probleme beim formalen Addieren
1011
+ 0001
1100
-3
+1
-4
3.2.4 Ganze negative Zahlen: Zweierkomplement
 Zweierkomplementdarstellung
 Negative Zahl durch bitweise
 0000 = 0
1000 = -8
0001 = 1
1001 = -7
0010 = 2
1010 = -6
0011 = 3
1011 = -5
0100 = 4
1100 = -4
0101 = 5
1101 = -3
0110 = 6
1110 = -2
0111 = 7
1111 = -1
 Vorteile
-2n ... +(2n-1)
Komplementierung und Addition von 1.
Beispiel: 3
0011 Binärdarstellung
1100 Komplement
1101 Komplement + 1 = -3
 Darstellung des Vorzeichens im ersten Bit
 Abdeckung von 16 Zahlen, also keine Redundanz
 Kein Nachteil durch Probleme beim formalen Addieren
 Subtraktion durch Addition des Zweierkomplements (Überlauf weglassen)
-3 1101
+1 +0001
-2 1110
-1 1111
-1 +1111
-2 11110  1110 (Überlauf weggelassen)
3.2.5 Gebrochene Zahlen: Binärdarstellung
 Darstellung mit Vor- und Nachkommateil
 Beispiele
Gebrochene Binärzahl
0.1
0.01
111.111
0.0001 1001 1001 1001 ....
Gebrochene Dezimalzahl
0,5
0,25
7,875
0,1
 Mit 32 Bit lassen sich nur 232 verschiedene Zahlen darstellen.
 Problem: extrem große und extrem kleine Zahlen lassen sich mit
wenigen Bits nicht darstellen
 Bei 8 Bit mit 4 Vorkomma und 4 Nachkommastellen (ohne Vorzeichen):
0000.0001 < n < 1111.1111
0,0675 < n < 15,9425
3.2.5 Gebrochene Zahlen: Exponentialdarstellung
 Anforderung
 sehr große und sehr kleine Zahlen sollen darstellbar sein
 Masse Elektron = 9 * 10-28 g
 Anzahl Moleküle pro Mol = 6,022 * 1023
 die relativen Genauigkeiten sind wichtiger als die absoluten
 Ältere Quellen geben die Anzahl der Moleküle pro Mol mit 6,065 * 1023 an
 Eine Änderung in der Mantisse von  0,04 entspricht einer Toleranz von 6,065 /
6,022  1,0071 also ca. 0,7%.
 Fixkommadarstellung wäre große Verschwendung
 zur Darstellung dieser beiden Größen wären 194 Bit nötig
 87 Bit Vorkommateil
 107 Bit Nachkommateil
 Idee: Signifikante Stellen und Größenordnung werden getrennt
 Signifikant Masse Elektron: 9
 Größenordnung Masse Elektron: 10-28
3.2.5 Gleitpunktzahlen: Real Darstellung
 Darstellung durch Real-Zahlen, bestehend aus drei Teilen:
 Vorzeichenbit V
Gibt an, ob die Zahl positiv oder negativ ist
 Mantisse M
Wird mit dem Exponenten multipliziert
 Die Normalform wird erreicht, indem das Komma soweit nach links oder rechts
geschoben wird, bis die erste Stelle nach dem Dezimalpunkt die erste von Null
verschieden Ziffer ist.
Der Exponent wird entsprechend der Verschiebungen erhöht oder vermindert.
 Exponent E
Potenz einer Basiszahl (2) mit der die Mantisse multipliziert wird
 wird oft in „BIAS“-Darstellung abgelegt, d.h. wird mit 126 addiert um negatives
Vorzeichen zu vermeiden.
 Vorsicht: 126 (nicht 128).
Asymmetrisch, da 21 bei der Normalisierung zweimal geschoben wird, 2-1 gar
nicht
 Vorsicht: Bei manchen Maschinen wird so normalisiert, dass die erste
Stelle vor dem Komma gleich 1 wird, dann ist der BIAS 127
3.2.5 Gleitpunktzahlen: Umwandlung
 Umwandlung Dezimalzahl in binäre Gleitpunktzahl (nach IEEE 754)
 Umwandlung der Dezimalzahl in Binärzahl mit Nachkommateil
 Verschieben des Kommas nach links oder rechts bis zur Normalform
 Damit ist erste Nachkommastelle = 1 und daher redundant, kann also in der
Mantisse weggelassen werden. 2 * größere Genauigkeit der Mantisse
 Addition des BIAS =126 (um negative Exponenten zu vermeiden)
Umwandlung in binäre Form
 Das Vorzeichen der Mantisse wird bestimmt: positiv 0, negativ 1
 IEEE 754 sieht noch eine optionale Rundung der Mantisse vor
 Nicht jede gebrochene Dezimalzahl lässt sich endlich als gebrochene
Binärzahl darstellen (und umgekehrt).
 Dadurch entstehen Rundungsfehler
3.2.5 Gleitpunktzahlen: Beispiele
 Beispiel: 148,62510
1. Konvertieren:
2. Normalisieren:
3. Bias addieren
4. Vorzeichen
5. Ergebnis:
10010100,101
10010100,101 = 0,10010100101*2+8 Exponent ist 8.
M
= 0010100101
(die führende 1 ist in Normalform redundant)
E
= 12610 + 810 = 13410 = 100001102
V
= 0
VEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM
01000011000101001010000000000000
 Beispiel: -2,7510
1. Konvertieren:
2. Normalisieren:
3. Bias addieren
4. Vorzeichen
5. Ergebnis:
10,11
10,11 = 0,1011*2+2 Exponent ist 2.
M
= 011
(die führende 1 ist in Normalform redundant)
E
= 12610 + 210 = 12810 = 100000002
V
= 1
VEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM
11000000001100000000000000000000
3.2.5 Gleitpunktzahlen: Arithmetik
 Addition/Subtraktion
 Die Exponenten werden angeglichen, indem die Mantisse des Operanten
mit dem kleineren Absolutbetrag entsprechend verschoben wird.
 Anschließend werden die Mantissen addiert
 Beim Verschieben können Stellen verloren gehen.
 Multiplikation
 Die Mantissen der Operanten werden multipliziert
 Die Exponenten werden addiert
 Sind die Exponenten zu groß, kann es zu Exponenten-Overflow kommen
 Division
 Die Mantissen der Operanten werden dividiert
 Der Exponent ergibt sich aus der Differenz des Dividenden und Divisors
 Ist der Divisor zu klein und/oder der Dividend zu groß kann es zu einem
Exponenten-Underflow kommen.
Das Ergebnis wird dann zu 0, alle Ziffern sind verloren
 Nach allen Operationen wird die Normalform ggf. wiederhergestellt
3.2.6 Standards





Short
-128 ... 127
Integer
-32768 ... 32767
Unsigned Int
0 ...65535
LongInt
-2147483648 ... 2147483647
Real nach IEEE 754
(8Bit)
(16Bit)
(16Bit)
(32Bit)
 Float
1 VZ-Bit, 8 Bit E, 23 Bit M
 Double
1 VZ-Bit, 11 Bit E, 52 Bit M
 zwei Varianten 0,5  M < 1 bzw. 1  M < 2
(32Bit)
(64Bit)
Number
sign
exponent
mantissa
normalized number
0/1
01 to FE
any value
denormalized number
0/1
00
any value
zero
0/1
00
0
infinity
0/1
FF
0
NaN
0/1
FF
any value but 00
3.2.6 Standards: Beispiel (Delphi)
 In Borlands Delphi (Pascal) sind folgende Typen festgelegt:







Typ
Real48
Single
Double
Extended
Comp
Currency
Bereich
2,9 x 10^-39
1,7 x 10^38
1,5 x 10^-45
3,4 x 10^38
5,0 x 10^-324 1,7 x 10^308
3,6 x 10^-4951 1,1 x 10^4932
-2^63+1
2*63-1
-922337203685477.5808
+922337203685477.5808
Signifikant
11-12
7-8
15-16
19-20
19-20
19-20
Größe
6
4
8
10
8
8
 Der generische Typ Real ist in der aktuellen Implementierung mit dem
Typ Double identisch.
3.3
Zusammenfassung des Kapitels
 Kodierung von Zeichen
 ASCII
 EBCDIC
 UNICODE
 Darstellung von Zahlen








Zahlensysteme
Konvertierung
Arithmetik
Ganze positive Zahlen
Ganze negative Zahlen
Gebrochene Zahlen
Gleitpunktzahlen
Standards
Kapitel 4
Datenstrukturen
 Information aus der realen Welt werden in einem informationsverarbeitenden System als Daten abgelegt. Diese stellen also eine
(vereinfachte) Abstraktion der Wirklichkeit dar und spiegeln in vielen
Fällen die Strukturen der Wirklichkeit wider.
In diesem Kapitel wird ein Überblick über die wichtigsten abstrakten
Datenstrukturen gegeben, wobei dieser Begriff zum Begriff des
„Datentyps“ erweitert wird.
 Inhalt
1.
2.
3.
4.
Datenstrukturen - Datentypen
Datentypen: Ein Überblick
Konkrete Datentypen
Abstrakte Datentypen
4.1
Datenstrukturen - Datentypen
 In der Literatur wird meist der Begriff „Datenstruktur“ verwendet. In
diesem Unterkapitel soll der Unterschied ziwschen diesem Begriff und
dem Begriff des „Datentyps“ erläutert werden.
 Inhalt
1. Datenstrukturen
2. Datentypen
3. Variablen eines Datentyps
4.1.1 Datenstrukturen
 In der Informatik werden Objekte der realen oder abstrakten Welt
erfasst
 Bei der Erfassung beschränkt man sich möglichst auf die für den weiteren
Transport / Speicherung/Verarbeitung/Umsetzung notwendige Information
 Zur internen Repräsentation werden diese Objekte abstrahiert
 Zur Abstraktion gehört die Erkennung von Strukturen - im Sinne einer
Aggregation.
 Also
 Aus welchen Teilobjekten bestehen Objekte ?
 In welchem Verhältnis stehen die Teilobjekte zueinander ?
 Welches sind die „atomaren“ Teilobjekte ?
 Anschließend werden diese Objekte typisiert.
 Typisierung ist die Einteilung von abstrakten internen Objekten in Gruppen
mit gleichen oder ähnlichen Eigenschaften.
4.1.2 Datentypen
 Typen sind also nicht die intern repräsentierten Objekte, sondern
beschreiben die Eigenschaft einer Gruppe von Objekten.
 Zu diesen Eigenschaften gehören:






Struktur
Wertebereich
anwendbare Operatoren, Funktionen, Relationen
Beziehungen zu anderen Typen
interne Repräsentationsweise
…
Beispiel:
Imaginäre Zahlen
 Einige Anmerkungen::
 Der Begriff „Datentyp“ ist weitergehend als der Begriff „Datenstruktur“
 In der Objektorientierten Programmierung wird statt „Datentyp“ auch der
Begriff „Klasse“ verwendet (Klassen beschreiben mehr Eigenschaften)
 Konkrete Repräsentanten eines Datentyps werden (u.a) „Variable“ oder
- bei oo-Sprachen - „Instanz“ genannt
4.1.3 Variable eines Datentyps
 Einen speziellen Repräsentanten eines Datentyps bezeichnet man als
Variable. Die Festlegung, von welchem Datentyp eine Variable ist,
bezeichnet man als Variablendeklaration.
 Die Zuordnung eines Typs „Typ“ an eine Variable X wird (zunächst) wie
folgt notiert:
X : Typ;
 Eine Variable hat alle Eigenschaften eines Datentyps.
Zusätzlich dazu hat eine Variable:
 einen konkreten Wert.
 Der Wert muss aus dem Wertebereich des Datentyps sein (oder undefiniert)
 Die Zuweisung eines Wertes „Wert“ an eine Variable X sei (zunächst) wie folgt
notiert:
X = Wert;
 einen konkreten Speicherplatz
 Dieser Speicherplatz ist so dimensioniert, dass die Struktur der Variable
abgebildet werden kann
 Dieser Speicherplatz wird (meist) implizit durch die Deklaration zugeordnet
 Beispiel:
x : Datentyp; // x ist vom Typ: „Datentyp“
X = 531;
// Zuweisung von 531 an X
4.2
Datentypen: Überblick
 Nachdem sich nun der Begriff des „Datentyps“ als Oberbegriff der
„Datenstruktur“ erwiesen hat, konzentrieren wir uns im Rest des
Kapitels auf wichtige Datentypen.
In diesem Unterkapitel wird ein Klassifikationssystem für die in der
Informatik verwendeten Datentypen aufgestellt und kurz erläutert
 Inhalt
1. Klassifikation der Datentypen
2. Erläuterung der Klassifikation
4.2.1 Klassifikation der Datentypen
Datentypen
Konkrete
Einfache
Ordinale
Boolean
(Wahrheitswert)
Integer
(Ganzzahl)
Abstrakte
Pointer(Zeiger)
Real
(Fließkomma)
Char
(Zeichen)
Array
(Feld)
Idealisierte
Strukturierte
Record
Union
(Verbund) (Variantenverb.)
...
Enumeration
(Aufzählung)
4.2.2 Erläuterung der Klassifikation
 Idealisierte Datentypen
 aus der Mathematik bekannte Datentypen: R, N, Z, ...
 Variablen dieser Typen sind oft nicht endlich darstellbar (Bsp: 2)
 In einem Computer-Algebra-System symbolisch darstellbar (Bsp: 2^( 1/2))
 Konkrete Datentypen
 in einem Rechner von Hard- oder Software bereitgestellte Datentypen
 entweder vordefiniert oder durch den Benutzer definierbar
 Abstrakte Datentypen
 verbergen ihren inneren Aufbau vor dem Benutzer
 bestehen aus beliebigen Strukturen über konkrete/idealisierte Datentypen,
sowie aus Zugriffsfunktionen bzw. Prozeduren
 Beispiel: Baum
13
insert (Element)
6
2
61
12
15
delete (Element)
79
search (Element)
4.3
Konkrete Datentypen
 Die am häufigsten abstrahierten Objekte der realen Welt sind,
zumindest was die für eine weitere Verarbeitung notwendigen
Informationen betrifft, einfach strukturiert und lassen sich demnach mit
konkreten Datentypen abbilden.
Dieses Unterkapitel gibt einen Überblick über alle konkreten Datentypen
und beschreibt diese.
 Inhalt
1.
2.
3.
4.
Einfache Datentypen
Strukturierte Datentypen
Verweise
Abstrakte Datentypen
4.3.1 Einfache: boolean (Wahrheitswert)
 zur Darstellung von Wahrheitswerten
 Wertebereich: true, false
 intern in manchen Programmiersprachen als 1 bzw 0 dargestellt
 Operatoren: und, oder, nicht, Vergleiche, ...
 Operatoren entsprechend der bool‘schen Algebra
 oft auch allgemeine arithmentische Operationen möglich
 Vorsicht vor Integer-Arithmetik mit boolean-Variablen
 Notation:
 Beispiel:
booleanVar : boolean;
switch
switch
switch
switch
switch
:
=
=
=
=
boolean;
false;
not(switch);
switch and not(switch);
switch or not (switch);
//
//
//
//
=
=
=
=
0
not(0) = 1
1 and 0 = 0
0 or 1 = 1
4.3.1 Einfache: integer (Ganzzahl)
 zur Darstellung ganzer Zahlen mit oder ohne Vorzeichen
 Wertebereich: Unterschiedlich
 unsigned integer: Ganze Zahlen ohne Vorzeichen ( 0... 65535 )
 oft 16 bit bzw. 32 bit als shortInt bzw. longint bezeichnet
 Vorsicht:
16 bit Integer ist verdammt wenig ((± 32267)
Speicherplatz ist nicht mehr teuer  benutzen Sie longInt
(Ausnahmen bestätigen die Regel)
 Operatoren: Grundrechenarten, Vergleiche
 Operatoren entsprechend der „klassischen“ Algebra
 Notation:
 Beispiel:
integerVar : integer;
i
i
i
i
i
:
=
=
=
=
integer;
1;
i + 32;´
i / 17;
i + 65535;
//
//
//
//
= 1
= 1 + 32 = 33
= 33 / 17 = 1 !
bei unsigned Int.: Fehler !
4.3.1 Einfache: char (Zeichen)
 zur Darstellung von Zeichen
 Vorsicht: Typischerweise wird die ASCII-Codierung zugrundegelegt,
kann aber auch Unicode sein
 Wertebereich: Alle Zeichen
 Intern codiert als ASCII oder - neuerdings immer öfter - als Unicode
ASCII: 8 Bit (7 benutzt), Unicode: 16 Bit
 Intern oft als integer repräsentiert
 Operationen: Vergleich
 oft auch allgemeine arithmentische Operationen möglich
 Vorsicht vor Integer-Arithmetik mit boolean-Variablen
 Notation:
 Beispiel:
charVar : char;
symbol
symbol
symbol
symbol
:
=
=
=
char;
„A“;
symbol + 32;´
symbol - 128;
// = „A“
// = „A“ + 32 = „a“
// = „a“ - 128 = Fehler
4.3.1 Einfache: enum (Aufzählung)
 zur Darstellung endlicher benutzerdefinierter Wertebereich
 Es ist guter Stil, Mengen mit (garantiert) kleiner Mächtigkeit (<10) als
enum-Type zu deklarieren, anstatt sie z.B. als Integer zu kodieren.
 Intern werden enum-Werte oft als integer abgelegt
 Operatoren: Vergleich
 oft auch allgemeine arithmentische Operationen möglich
 Vorsicht vor Integer-Arithmetik mit enum-Variablen
 Notation:
 Beispiel:
enumVar : enum { Wertemenge };
ampelfarbe
ampelfarbe
ampelfarbe
ampelfarbe
ampelfarbe
:
=
=
=
=
enum {gruen,gelb,rot} ;
gruen;
// = gruen
ampelfarbe +1 ; ´ // = gruen + 1 = gelb
ampelfarbe +1 ; ´ // = gelb + 1 = rot
ampelfarbe +1 ; ´ // = rot + 1 = Fehler !
4.3.1 Einfache: real (Fließkomma)
 zur näherungsweisen Darstellung reeller Zahlen
 Wertebereich: Unterschiedliche Genauigkeiten und Wertebereiche
 Wertebereich entspricht typischerweise der IEEE 754 Norm, also:
 Float: 32 bit
 Double: 64 bit
 Operationen: Grundrechenarten, erweiterte Arithmetik, Vergleich
 Notation: realVar : real;
 Beispiel: //--- Variable-declaration -------------------------pi, flaeche, radius : real;
// all real !
//--- Initialisation -------------------------------pi
= 3,141; // needs not to be more accurate
radius = 5;
// might be changed by user
//--- Computation of surface -----------------------flaeche = 2 * pi * (radius ^ 2);
// common formula
4.3.2 Strukturierte: Array (Feld)
 Arrays sind eine Aggregationen von Daten des gleichen Typs
(des „Basistyps“)
 Die Grenzen des Arrays sind (meist) statisch bestimmt
 Operation: Auswahl
 Die Auswahl eines Datenelemtes über erfolgt über einen ganzzahligen Index
über den (Auswahl-)Operator „ [ ] “
 Vorsicht: Zugriff außerhalb des deklarierten Bereiches führt zu Fehlern
 Notation:
 Beispiele
ArrayVar : array[min .. max] of Datentyp
 Eindimensionales array:
 Zweidimensionales array:
Vektor : array[1..4] of real;
 Operator
m : array[1..3] of array[1..2] of real;
v : array[1..4] of real;
v[3] = 5,03; v[4] = 4,12;
m[1][2] = v[3] * 12 - v[4];
Matrix : array[1..3] of
array[1..2] of real;
4.3.2 Strukturierte: Record (Verbund)
 Verbunde sind Aggregationen von Daten möglicherweise unterschiedlichen Typs
 manchmals auch „structure“ oder „struct“ genannt
 Operation: Auswahl
 Die Auswahl erfolgt durch Angabe den des Komponentennamens
(durch einen Punkt vom Variablennamen getrennt)
 Notation:
recordVar : record
{
komponent1 : type1;
...
};
 Beispiel:
d : record
{
tag
: Integer;
monat : Integer;
};
d.monat = 10;
d.tag
= 20;
4.3.2 Strukturierte: Variant Record (Variantenverb.)
 Verbunde, deren Struktur mögliche Alternativen zulassen
 manchmals auch „union“ genannt
 lassen „Varianten“ eines Record-Types zu
 Operation: Auswahl (wie bei records über Punkt-Operator)
 Notation: varrecVar : record {
komponent1 : type_1;
...;
case variant (variant1,...) of {
variant1 : type_n;
...
}
TAGGED TYPE
(implizit)
}
 Unterelement „variant“ implizit definiert bei „tagged type“
 Nur ein Unterelement aus variant1, ... (sinnvoll) verwendbar
 Beispiel:
adam,eva : record {
name : array [1..20] of char;
case sex (m,f) of {
f: {IQ: integer};
m: {muscle: real}; // in cm
}
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
4.3.2 Strukturierte: Variant Record

adam,eva : record {
name : array [1..20] of char;
case sex (m,f) of {
f: {IQ: integer};
m: {muscle: real}; // in cm
}
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
 Umsetzung:
name
sex IQ /
muscle
 Variant Records mit „Untagged Types“ (z.B. C, C++ : Union)
struct {
char[20] name;
enum {m,f} sex;
union {
int IQ;
real muscle; // in cm
} adam, eva;
(2. Variante)
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
4.3.3 Verweis: Pointer (Zeiger)
 Mit einfacher Datentypen und mit den konkreten Datentypen „Liste“
und „Verbund“ lassen sich nur statische Struktur aufbauen
 d.h. Strukturen, deren Speicherbedarf beliebig aber fest sind
 Bem.: Die Beliebigkeit ist begrenzt durch die Gesamtspeicherkapazität
 Mit Zeiger-Datentypen lassen sich Strukturen aufbauen, die sich
dynamisch auf- und abbbauen lassen
 d.h. Strujturen, deren Speicherbedarf sich dynamisch verändern kann
 Bem.: Auch hier ist die Beliebigkeit begrenzt durch die Gesamtspeicherkapazität
 Beispiel:
knoten :
{
symbol
links
rechts
}
Huffman
(Bsp. aus Kap.2)
record
: char;
: Verweis;
: Verweis;
B
C
E
D
A
4.3.4 Vereinfachung der Notation („typedef“)

Person
: record { surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : record { year: integer;
month : enum {jan,...};
day
: integer; };
};
Akt_Datum : record { year: integer;
month : enum {jan,feb,...};
day
: integer; };
 In (fast) allen Programmiersprachen ist es möglich, beliebig strukturierte
Datentypen neu zu bezeichnen und diese Typ-Bezeichner wie
vordefinierte Typen zu verwenden:
 Notation: typedef NeuTyp : Typ;
 Beispiel: typedef Datum : record { year: integer;
month : enum {jan,feb,...};
day
: integer; };
Person:
record { surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : Datum };
Akt_Datum: Datum;
4.3.5 Beispiel: Kombination von Datentypen
 Um nun beliebig komplexe Strukturen der „realen“ Welt in einem
Rechensystem abbilden zu können, kann man die vorgestellten
Datentypen beliebig miteinander Kombinieren
 Beispiel.:
typedef Person : record { surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : record { year: integer;
month : enum {jan,feb,...};
day
: integer; };
next
: Verweis;
previous : Verweis; };
4.4
Abstrakte Datentypen
 Grundsätzlich lassen sich alle Objekte der realen Welt ausschließlich
mit Hilfe einfacher Datentypen abbilden. Diese Abbildung ist aber meist
„unnatürlich“, weil sie die Struktur realer Objekte nicht ausreichend
berücksichtigt. Abhilfe schaffen hier strukturierte Datentypen, die
allerdings grundsätzlich nur endliche Objektmengen repräsentieren
können. Hier schaffen Zeigertypen Abhilfe.
 Kann man nun mit diesen Mitteln Strukturen realer Objekt natürlich
abbilden, so fehlen diesen Datentypen einige der Eigenschaften, die
Datentypen von Datenstrukturen unterscheiden, dies sind insb.
 Operationen und
 Beziehungen zu anderen Typen.
 Einen vertieften Einblick in die bunte Welt abstrakter Datentypen bietet
die Vorlesung des 2. Semesters
Datenstrukturen
4.5
Zusammenfassung des Kapitels
Datentypen
Konkrete
Einfache
Ordinale
Abstrakte
Pointer(Zeiger)
Real
(Fließkomma)
Idealisierte
Strukturierte
Array Record Union
(Feld) (Verbund) (Variantenverb.)
...
Enumeration
Boolean
Integer
Char
(Wahrheitswert) (Ganzzahl) (Zeichen) (Aufzählung)
 Wir sind damit auch an die Grenzen dessen gelangt, was in dieser
Vorlesung über die „Statik“ von Objekten gesagt werden soll und
wenden uns einem noch spannenderem Themenbereich zu ;-)
Kapitel 5
Algorithmenentwurf
 In den vorangegangenen Kapiteln wurde, aufbauend auf dem Begriff
der Information, beschrieben, wie die statischen Objekte der Informatik
aussehen und notiert werden können.
In diesem Kapitel wird aufgezeigt, wie man die Verarbeitung dieser
Objekte (also die Dynamik) beschreiben kann. Wesentlicher Begriff
dabei ist der Begriff des Algorithmus
 Inhalt
1.
2.
3.
4.
5.
6.
Ein Beispiel
Definition
Die Struktelemente
Strukturierung
Blockung
Iteration und Rekursion
Teile dieses Kapitels sind aus:
R.Manthey: Vorlesung Informatik 1, Uni Bonn, 2001
5.1
Ein Beispiel
 Zunächst soll ein kleines Beispiel in eine mögliche Aufgabenstellung
aus dem (bekannten) Bereich der Mathematik einführen und dadurch
auch eine (eingeschränkte) Vorstellung über die Aufgaben und
Elemente eines Algorithmuses geben.
 Inhalt
1.
2.
3.
4.
5.
6.
7.
Das Problem (Beispiel)
Ein Algorithmus I
Ein Algorithmus II
Vergleich der Algorithmen
Ein Algorithmus III
Fragestellungen
Ein weiterer Algorithmus
5.1.1 Das Problem
 Eine quadratischen Gleichung:
x2 + 8x + 7 = 0
 Allgemeine Darstellung der quadratischen Gleichung
x2 + px + q = 0
 Allgemeine Lösung der quadratischen Gleichung
x1,2= -p/2 +- p2/4 - q
 Lösung der quadratischen Gleichung
x1,2 = -8/2 += -4
+
82/4 - 7
- 3
x1 = -1
x2 = -7
5.1.3 Ein Algorithmus I
 Ein Algorithmus
x1,2= -p/2 +- p2/4 - q
Zuweisungen
Berechnungen
Eingaben
1. Lies die Zahlen p und q ein
2. Berechne die Zahl w = p2/4 - q
Konstante
3. Berechne die Zahl x1 = -p/2 + w
4. Berechne die Zahl x2 = -p/2 - w
5. Gib x1 und x2 als Ergebniss aus
Variable
Ausgaben
5.1.4 Ein Algorithmus II
 Ein zweiter Algorithmus
1. Lies die Zahlen p und q ein
x1,2= -p/2 +- p2/4 - q
2. Berechne die Zahl p/2; Nenne diese Zahl a
3. Berechne die Zahl a2 ; Nenne diese Zahl b
4. Berechne die Zahl b-q ; Nenne diese Zahl c
5. Berechne die Zahl c ; Nenne diese Zahl d
6. Berechne die Zahl -a ; Nenne diese Zahl e
7. Berechne die Zahl e + d ; Nenne diese Zahl x1
8. Berechne die Zahl e - d ; Nenne diese Zahl x2
9. Gib x1 und x2 als Ergebniss aus
FHSymbol1
Es gibt (oft unendlich) viele Algorithmen zur
Lösung eines Problems
5.1.5 Vergleich der Algorithmen
Berechne die Zahl w = p2/4 - q
Berechne die Zahl p/2; Nenne diese Zahl a
Berechne die Zahl x1 = -p/2 + w
Berechne die Zahl a2 ; Nenne diese Zahl b
Berechne die Zahl x2 = -p/2 - w
Berechne die Zahl b-q ; Nenne diese Zahl c
Berechne die Zahl c ; Nenne diese Zahl d
Berechne die Zahl -a ; Nenne diese Zahl e
Berechne die Zahl e + d ; Nenne diese Zahl x1
Berechne die Zahl e - d ; Nenne diese Zahl x2
Anzahl Berechnungen
Anzahl Zuweisungen
Anzahl Variablen
A1
10
3
5
A2
7
7
9
FHSymbol1
Welcher
Algorithmus
ist besser ?
Warum ?
5.1.6 Ein Algorithmus III
 Problem: Negatives Wurzelargument
1.
Lies die Zahlen p und q ein
2.
Berechne die Zahl a = p/2
3.
Berechne die Zahl b = a2
4.
Berechne die Zahl c = b-q
5.a Wenn c negativ ist brich den
Algorithmus ab
Ansonsten mache mit nächstem
Schritt weiter
6.
Berechne die Zahl d = c
7.
Berechne die Zahl e = -a
8.
Berechne die Zahl x1 = e + d 1
9.
Berechne die Zahl x2 = e - d
10. Gib x1 und x2 als Ergebniss aus
5.b Wenn c negativ ist
gehe zu Schritt 1
Bedingte
Ausführung
Schleife
5.1.7 Fragestellungen
1.
Lies die Zahlen p und q ein
2.
Berechne die Zahl a = p/2
3.
Berechne die Zahl b = a2
4.
Berechne die Zahl c = b-q
6.
Berechne die Zahl d = c
7.
Berechne die Zahl e = -a
8.
Berechne die Zahl x1 = e + d 1
9.
Berechne die Zahl x2 = e - d
10. Gib x1 und x2 als Ergebniss aus
FHSymbol1
Welche offenen
Fragen bestehen
noch ?














Wer gibt p und q ein ?
Wie wird p und q eingegeben ?
Werden p und q in endlicher Zeit
eingegeben ?
Sind p und q im richtigen Format ?
Ist Variable a im richtigen Format ?
Gibt es die Quadrat-Funktion ?
Ist c positiv ?
Ist Variable e im richtigen Format ?
Sind die restlichen Variablen im richtigen
Format
Reicht die Genauigkeit der Darstellung ?
Wo wird das Ergebnis ausgegeben ?
Ist ausreichend Variablenkapazität für den
Algorithmus vorhanden ?
Läuft der Algorithmus schnell genug ?
...
5.1.8 Ein weiterer Algorithmus
5.2
Definition
 Der Begriff des Algorithmus ist zentral in der Informatik und soll in
diesem Unterkapitel formal definiert werden
 Inhalt
1.
2.
3.
4.
5.
6.
Herkunft
Der Algorithmus
Beispiel: Algorithmenbeweis
Weitere Prinzipien
Algorithmen und Programme
Ausflug: Algorithmus und WinOSe
5.2.1 Herkunft
 Muhammad ibn Musa abu Djafar al-Choresmi (ca. 780-850 n.Chr)
 arabischer Mathematiker, geboren in Choresmien (heute: Usbekistan)
 lebte und wirkte in Bagdad im „Haus der Weisheit“
 war beteiligt an der Übersetzung der Werke griechischer Mathematiker ins
Arabische
 schrieb ein „Kurzgefasstes Lehrbuch für die Berechnung durch Vergleich
und Reduktion“
 die lateinische Übersetzung dieses Buches („liber algorismi“) kam durch
Kreuzfahrer nach Europa
 verfasste auch ein Buch mit dem Titel „Al-Mukhtasar fi Hisab al-Jahr va lMuqabala“
Algorithmus
Algebra
5.2.2 Der Algorithmus
 Definition:
Ein Algorithmus (algorithm) ist die Beschreibung eines Verfahrens, um
aus gewissen Eingabegrößen bestimmte Ausgabegrößen zu
berechnen. Dabei müssen folgende Bedingungen erfüllt sein
 Spezifikation
 Durchführbarkeit
 Korrektheit
 Verfahren ohne Verständnis des Problemes
FHSymbol1
Erwarten Sie nie, dass ein
Computer für Sie mitdenkt
5.2.2 Der Algorithmus : Spezifikation
 Eingabespezifikation:
 Es muss genau spezifiziert sein, welche Eingabegrößen erforderlich sind
und welchen Anforderungen diese Größen genügen müssen, damit das
Verfahren funktioniert
EINGABE
Algorithmus
 Ausgabespezifikation
 Es muss genau spezifiziert sein, welche Ausgabegrößen (Resultate) mit
welchen Eigenschaften berechnet werden
5.2.2 Der Algorithmus : Durchführbarkeit
 Endliche Beschreibung
 das Verfahren muss in einem endlichen Text vollständig beschrieben sein
 Effektivität
 Jeder Schritt des Verfahrens muss effektiv (d.h. tatsächlich) „mechanisch“
ausführbar sein
Bem.: „Effektivität“ ist nicht zu verwechseln mit „Effizienz“
(„Wirtschaftlichkeit“)
 Determiniertheit
 Der Verfahrensablauf ist zu jedem Zeitpunkt fest vorgeschrieben
5.2.2 Der Algorithmus : Korrektheit
 partielle Korrektheit
 Jedes berechnete Ergebnis genügt der Ausgabespezifikation, sofern die
Eingaben der Eingabespezifikation genügt haben
 Terminierung
 Der Algorithmus hält nach endlich vielen Schritten mit einem Ergebnis an,
sofern die Eingaben der Eingabespezifikation genügt haben
5.2.2 Der Algorithmus : Zusammenfassung
 Definition
Ein Algorithmus (algorithm) ist die Beschreibung eines Verfahrens, um
aus gewissen Eingabegrößen bestimmte Ausgabegrößen zu
berechnen,
der gekennzeichnet ist durch:







Spezifikation der Ein- und
Ausgabegrößen
eine endliche Beschreibung des Verfahrens
effektive Ausführbarkeit der Verfahrensschritte
Determiniertheit der Verfahrensschritte
partielle Korrektheit
Terminiertheit
 Bemerkung:
 Algorithmen, die eine oder mehrere dieser Eigenschaften nicht besitzen
werden dann als Nicht-<Eigenschaft> Algorithmen bezeichnet.
 Bsp: Nicht-Deterministische Algorithmen.
5.2.3 Beispiel: Algorithmenbeweis
 In gängiger mathematischer Notation könnte ein Verfahren zur
Berechnung der Modulus-Funktion a mod b wie folgt aussehen:
 a
falls a < b
mod(a,b) = 
 mod(a-b,b) falls a  b
 Um festzustellen, ob diese Berechnungsvorschrift einen Algorithmus im
Sinne der Definition darstellt, müssen folgende Punkte beachten werden:
 Spezifikation
 Eingabe
 Ausgabe
 Durchführbarkeit
 Endliche Beschreibung
 Effektivität
 Determiniertheit
 Korrektheit
 Partielle Korrektheit
 Terminierung
5.2.3 Beispiel: Spezifikation
 Lassen sich die möglichen Ein- und Ausgabewerte genau spezifizieren
?
5.2.3 Beispiel: Durchführbarkeit
 Ist der Algorithmus durchführbar ?
5.2.3 Beispiel: Korrektheit (partielle)
 Ist der Algorithmus korrekt (im Sinne der Spezifikation)
5.2.3 Beispiel: Korrektheit (Terminierung)
 Terminiert der Algorithmus ?
 Bemerkung: Es gibt kein Verfahren, das zu einem beliebigen Algorithmus
angibt, ob er terminiert oder nicht („Halte-Problem“)
5.2.3 Weitere Prinzipien
 Neben den in der Definition angegebenen Eigenschaften gibt es weitere
wichtige Prinzipien, die bei der Erstellung eines Algorithmuses zu
beachten sind:
 Effizienz
 Der Algorithmus soll möglichst wenig Aufwand verursachen
– Das Ergebnis mit möglichst wenig Rechenschritten (oder mit möglichst wenig
Speicherbedarf) erzielen
 Korrektheit beweisbar?
 Ein nicht-korrekter Algorithmus ist nach unserer Definition kein Algorithmus!
 Trotzdem sind nicht-korrekte Verfahren eher die Regel als die Ausnahme
5.2.4 Algorithmen und Programme: Der Weg
Algorithmierung
Programmierung
Problem
Algorithmus
Programm
Spezifizieren
Verifizieren
Testen
 gegeben: das Problem
 durch Spezifizieren wird das Problem formal beschrieben
 Durch Algorithmierung (Algorithmenentwurf) wird ein Algorithmus
erzeugt
 durch Verifizieren kann der Algorithmus auf Übereinstimmung mit der
Spezifikation überprüft werden
 Durch Programmieren wird aus den Algorithmus ein Programm erzeugt
 durch Testen kann das Programm auf Übereinstimmung mit der
Spezifikation und dem Algorithmus überprüft werden.
5.2.4 Algorithmen und Programme: Beziehungen
Algorithmierung
Problem
Programmierung
Algorithmus
Programm
 Programmieren setzt Algorithmenentwicklung voraus
 Kein Programm ohne Algorithmus !
 Jedes Programm repräsentiert einen bestimmten Algorithmus.
 Ein Algorithmus kann durch viele Programme repräsentiert werden.
Problem
Algorithmus1
Algorithmus2
Programm21
Programm22
...
...
5.2.5 Ausflug: Algorithmus und WinOSe
Klassische
Programmierung
Windows
Programmierung
OS
Algorithmus
OS
Eventqueue
5.3
Strukturelemente
 Um die Dynamik - also die Abfolge von Aktionen - eines Algorithmuses zu beschreiben, benötigt man formale Beschreibungsmittel,
sowie eine Festlegung, wie diese Beschreibungmittel zu notieren und
zu interpretieren sind.
Dieses Unterkapitel stellt die formalen Beschreibungsmittel für
Algorithmen vor. Diese Beschreibungsmittel sind dabei gleichzeitig
Strukturierungselemente für Algorithmen, denn sie definieren die
Struktur von Algorithmen.
 Inhalt:
1.
2.
3.
4.
Die Elemente
Folge
Auswahl
Wiederholung
5.3.1 Die Elemente: Aus dem Beispiel
EINGABE
 Zuweisungen
 Berechnungen
 Variable
 Mathematische
Grundoperationen
 komplexe Funktionen
 ...
 Bedingte Ausführungen
 Schleife
 ...
AUSGABE
 Texte
 Zahlen ...
 Konstanten
(Literale)
 Texte
 Zahlen ...
5.3.1 Die Elemente: Notation
 Für die Beschreibung von Algorithmen gibt es viele Möglichkeiten
 Alltagssprache
 Konkrete Programmiersprache
 Dazwischen gibt es eine Vielzahl von Notationen, die den Übergang
zwischen Problembeschreibung und Programm erleichtern sollen
 Eine mögliche - eindimensionale - Notation ist Pseudocode:
 // Dies ist eine Zuweisung
x = 42;
 Kommentare werden (hier) mit vorangestellten Slashes „//“ gekennzeichnet
 Aktionen werden (hier) mit Semikolon „;“ getrennt
 Visualisierung durch graphische - zweidimensionale -Notation
 Flussdiagramme
 Struktogramme (=Nasi-Schneidermann-Diagramme)
Aktion
Aktion
5.3.1 Die Elemente: atomare Elemente
 Anweisungen sind die atomaren Elemente eines Algorithmus‘, die
Elemente also, aus denen ein Algorithmus aufgebaut ist.
 Es gibt (zunächst) drei Arten dieser „atomaren“ Elemente
 Zuweisung:
 Pseudocode
X = y;
 Auf der linken Seite der Zuweisung steht eine Variable auf der rechten Seite der
Zuweisung steht entweder eine Variable, ein Literal oder eine Berechnung aus
Varaibelen und Literalen
 Eingabe
 Pseudocode:
x << <Eingabegerät> ;
 Als Eingabegerät kann ein geeignetes physikalisches Gerät (Tastatur,
Schnittstelle, ...) angegeben werden.
 Ausgabe
 Pseudocode:
x >> <Ausgabegerät> ;
 Als Ausgabegerät kann ein geeignetes physikalisches Gerät (Bildschirm,
Drucker, Schnittstelle, ...) angegeben werden
 Ein- und Ausgabe können auch als Zuweisung verstanden werden.
5.3.1 Die Elemente: Kontrollelemente
 Die atomaren Elemente eines Algorithmuses können durch drei
einfache Strukturierungsmethoden, den „Kontrollelementen“,
zueinander in Beziehung gesetzt werden:
1. Folge (Sequenz)
2. Auswahl (Selektion, Fallunterscheidung)
3. Wiederholung (Iteration, Schleife)
 Die Kontrollelemente bestimmen die Reihenfolge von Aktionen in
Algorithmen
 Eine Aktion (Ai) - auch Verarbeitung genannt - ist ein atomares Element
oder eine durch die Strukturmethoden zusammengefasste Menge
mehrerer Aktionen
5.3.2 Folge
 Folgen bestimmen die lineare Reihenfolge von Aktionen in Algorithmen:
 Flussdiagramm
Struktogramm
Pseudocode:
A1
A2
..
.
An
A1
A2
{
..
.
An
}
A1;
A2;
...
An;
5.3.3 Auswahl : bedingte Verarbeitung
 Eine Aktion wird, in Abhängigkeit einer bool‘schen Bedingung
ausgeführt oder nicht
 auch „einarmiges if“ genannt.
 Flussdiagramm
Struktogramm
Pseudocode:
f
B
w
w
B
f
A1
A1
 Beispiel:
if (x<0) then x = -x;
if B then A1;
5.3.3 Auswahl : einfache Alternative
 In Abhängigkeit einer bool‘schen Bedingung wird entweder eine Aktion
oder eine andere Aktion ausgeführt
 auch „zweiarmiges if“ genannt.
 Flussdiagramm
w
B
Struktogramm
f
w
A1
A1
 Beispiel:
B
f
A2
Pseudocode
if B then A1
else A2;
A2
if (x<0) then x:=-x else x=0;
5.3.3 Auswahl : mehrfache Alternative
 In Abhängigkeit einer Bedingung (mit mehreren möglichen Werten w1,
w2, ..., wn) wird eine Aktion aus einer Menge möglicher Aktionen
ausgewählt und ausgeführt
 Flussdiagramm
Struktogramm
Pseudocode
B
w1
w2
A1 A2
 Beispiel:
w1
wn
B
A1 A2
wn
An
An
switch x: {
case 0: x = x/2;
case 1: x = x+1;
}
 Oft auch mit „else“-Alternative (statt wn)
switch
{
case
case
...
case
}
B:
w1: A1;
w2: A2;
wn: An;
5.3.4 Schleife: mit vorausgehender Prüfung
 Solange eine bool‘sche Bedingung erfüllt ist, wird eine Aktion
ausgeführt.
 Die Bedingung wird vor der ersten Ausführung der Aktion geprüft
 heißt auch: abweisende Schleife (While-Schleife)
 Flussdiagramm
Struktogramm
f
B
B
A1
w
A1
 Beispiel:
while x < 100 {
x = x + 1;
}
Pseudocode
while B
{
A1
}
5.3.4 Schleife: mit nachfolgender Prüfung
 Solange eine bool‘sche Bedingung erfüllt ist, wird eine Aktion
ausgeführt.
 Die Bedingung wird (erst) nach der ersten Ausführung der Aktion geprüft
 heißt auch: Do-While-Schleife
 Manchmal auch als Variante „Repeat-Schleife“ - z.B. in Pascal - aber:
Die „repeat-Schleife“ wird solange ausgeführt bis eine bool‘sche
Bedingung erfüllt ist.
 Flussdiagramm
B
A1
B
Struktogramm
f
A1
Pseudocode
do
{
A1
} while B
w
 Beispiel:
do { x = x + 1; } while x <= 100
5.3.4 Schleife: Beispiel (abweisende Schleife)
 Untersuche ob eine gegebene natürliche Zahl Primzahl ist.
 p > 2 ist Primzahl, falls sie durch kein t mit 1<t<p teilbar ist (p mod t  0)
 Idee:
 wenn p Primzahl, dann ist p ungerade
 es genügt, nur ungerade t zu untersuchen
 es genügt, nur solche t zu untersuchen die kleiner p sind,
 Algorithmus:
p << Tastatur;
if ((p>2) and (p mod 2 != 0)) then {
t = 3; // initialize t
while ((t*t<p) and (p mod t != 0)) {
t = t + 2;
} // nach Schleife ist t*t >=p oder p mod t == 0
if (t*t>p) then „p ist Primzahl“ >> Bildschirm;
else „p ist keine Primzahl“ >> Bildschirm;
}
else
{ „p <= 2 oder p gerade“ >> Bildschirm; } // Primzahl ?
5.3.4 Schleife: Beispiel (Vergleich while  do-while)
 Sind diese Schleifen im Ergebnis identisch ?
while x < 100
{
x = x + 1;
}
 und jetzt ?
do
{
x = x + 1;
} while x < 100
if (x < 100) then {
do {
x = x + 1;
} while x < 100
}
 Welche Lösung ist eleganter ?
 aber: oft wird eine erstmalige Aktion benötigt, um ein Datum überhaupt
überprüfen zu können.
5.3.4 Schleife: Beispiel (Vergleich do-while  while)
 Suchen eines Zeichens
do
{
x << Datei;
} while (
x != SearchChar
&& x != eof
)
 ... das Ganze als while-Schleife ?
while (
x != SearchChar
&& x != eof
)
{
x << Datei;
}
 Noch‘n Versuch:
x << Datei;
while (
x != SearchChar
&& x != eof
)
{
x << Datei;
}
5.3.4 Schleife: Beispiel (Schleife mit Zählern)
 Sehr häufig werden Schleifen verwendet, deren Bedingung abhängig
von Zählerwerten sind.
 Die Zählerwerte werden vor Eintritt in die Schleife initialisiert
 Die Bedingung prüft den Zählerwert
 Im Schleifenkörper wird der Zähler erhöht (increase) oder erniedrigt
(decrease)
 Vorsicht mit: dem Zählertyp, dem Additionswert, der Bedingung
 Algorithmus:
// --- Initialisierung -----------------------------s = 0;
i = 1; // Initialisierung des Schleifenzählers
// --- Schleife (Berechnet Summe 1..n) ------------while ( i <= n )
{
s = s + i;
i = i + 1; // Erhöhung des Schleifenzählers (oft um 1)
}
5.2.4 Schleife: Die „For“-Schleife
 Da Schleifen mit Zähler sehr häufig auftreten, stellen viele
Programmiersprachen ein eigenes sprachliches Mittel dafür zur
Verfügung: Die „For“ Schleife
 Pseudocode:
Beispiel:
for var=start_value to end_value
for i=1 to 10
{
{
A;
x = x + i;
}
}
 Der Zähler (var) wird pro Schleifendurchlauf implizit um 1 erhöht
(Bei manchen Sprachen - z.B. Basic, C, C++ - kann man dies ändern)
 Dieser Code ist äquivalent mit folgender Schleife:
i = start_value
while i <= end_value
{
A;
i = i+1;
}
5.3.4 Schleife: Beispiel (Endlosschleife)
 Manchmal macht es Sinn, Schleifen endlos laufen zu lassen:
 z.B. bei der zyklischen Abprüfung von Systemzuständen (Windows EventQueue)
 manchmal macht das keinen Sinn - passiert aber trotzdem ;-)
 Flussdiagramm
Struktogramm
B
A1
A1
 Beispiel:
Pseudocode
while true
{
A1
}
while true {
„Druckerpapier ist teuer“ >> Drucker;
}
5.4
Strukturierung
 Mit Hilfe atomarer Elemente und der Kontrollelemente lassen sich
Algorithmen strukturieren. In diesem Kapitel sind einige Begriffe zur
Strukturierung erläutert. Insbesondere wird ein weiteres - viertes Kontrollelement vorgestellt (und auch gleich wieder verworfen)
 Inhalt
1.
2.
3.
4.
Control Flow
Strukturierung durch Sprung
Strukturiert-iterative Beschreibungsform
Strukturierungstypen
5.4.1 Control Flow
 Mithilfe der Kontrollelemente können die „atomaren“ Elemente
(Anweisungen) strukturiert werden
 Die Anordnung der Anweisungen (als atomare Elemente) eines
Algorithmus, die bestimmt, in welcher Reihenfolge Dinge geschehen,
heißt
 control flow (Steuerungsverlauf, Kontrollfluss) des Algorithmus genannt
 Manchmal wird auch der Programmablauf oder Kontrollfaden (thread of
control, thread), also die tatsächlich abgespulten Schritte und Anweisungen
so bezeichnet
5.4.2 Strukturierung durch Sprung
 Bei der Vorstellung der Kontrollelemente wurde (aus hinterhältig,
didaktischen) Gründen auf ein viertes Element verzichtet:
Der Sprung („Goto“-Anweisung)
 Die Konstruktion „fahre fort mit Schritt x“ (goto x) stellt einen solchen
Sprung (jump) im Steuerungsverlauf dar
 Zur Anwendung von goto werden Schritte mit einer Marke (Label)
versehen, um das Ziel des Sprunges zu kennzeichnen
 Dies ist die elementarste Form, eine Wiederholung oder sonstige
Verzweigung im Ablauf auszudrücken
 Dadurch erhalten wir die elementar-iterative Beschreibungsform von
Algorithmen, die die Strukturierung mit ein-/mehrfacher Auswahl und
Schleifen funktional abdeckt.
 Beispiel:
while x<100 {
x = x+1
}
1: if x>100 goto 2
x = x+1;
goto 1;
2: ...
5.4.2 Strukturierung durch Sprung
 Anwendung von Sprüngen ist sehr gefährlich!
 Sprünge strukturieren komplexe Programm nicht ausreichend - der
Steuerungsverlauf kann verworren und unübersichtlich sein
 Um den Steuerungsverlauf auch bei komplexen Algorithmen
übersichtlich zu halten, schränkt man die Sprünge ein:
 Schleifen der Flussdiagramme sind höchstens ineinander geschachtelt
 Schleifen überkreuzen sich nicht!
 Bei gut strukturierten Algorithmen würde man z. B. nur wieder eine
geschlossene Schleife oder einen (vorzeitigen) Sprung bedingt durch
die Behandlung des Trivialfalls erlauben
 Wir sprechen in diesem Fall von strukturierten Sprüngen im Gegensatz
zu freien Sprüngen, die prinzipiell beliebige Ziele haben können
5.4.3 Strukturiert-iterative Beschreibungsform
 Sprünge können die bestimmte „höhere“ Strukturierungsarten
funktional abzubilden.
Hier gilt auch der Umkehrschluss
 In der strukturiert-iterativen Beschreibungsform kommen Sprünge
nur noch implizit bei der Ausführung höherer Iterationsstrukturen vor
 Dieses sind Fallunterscheidungen (Auswahl) wie if-then-else
 oder insbesondere Schleifenkonstrukte
 Diese bewirken, dass der Programmfluss
 In einer Auswahl zu genau einer Auswahl geht.
 in einer Schleife von einer Prüfung zu den Aktionen des Schleifenkörpers
und wieder zurück zur Prüfung geht.
 Viele höhere Programmiersprachen (Pascal, C, C++) erlauben jedoch
die Verwendung von Sprüngen
 Aus Optimierungsgründen (Nähe zur Maschinensprache)
 Aus Strukturierungsgründen)
5.4.4 Strukturierungstypen
 Beispiel: Schemen einiger Kontrollflüsse
Strukturiert-iterativ
Elementar-iterativ
Spaghetti-Code
5.4.5 Strukturierung durch Blockung
 Idee:
Eine Zusammenfassung von Aktionen bekommt einen Namen und kann
durch das Nennen des Namens (Aufruf) aktiviert werden.
 In einen Block können Daten formal hinein und herausgelangen.
 Ein Block kann eigenen Daten besitzen.
 Vorteile:
 Gliederung des Algorithmus‘ durch hierarchische Dekomposition
(„Divide et impera: Teile und herrsche“)
 Wiederverwendbarkeit durch mehrfachen Aufruf statt durch mehrfaches
notieren.
 universeller ( Anzahl muss nicht bekannt sein)
 fehlerunanfälliger
 Kapselung unwichtiger Details („information Hiding“)
 Vorteile bei der Organisation von Programmiertätigkeit durch Verteilbarkeit
der Aufgaben.
5.5
Zusammenfassung des Kapitels
 Ein Beispiel
 Drei Algorithmen im Vergleich zur Lösung einer quadratischen Gleichung
 Definition des Algorithmenbegriffes
 Definition und dessen Anwendung im Beispiel. Weitere Prinzipien und der
Zusammenhang von Algorithmen und Programmen.
 Strukturelemente:
 Die „atomaren“ Elemente und die Konstruktionselemente Folge, Auswahl,
Wiederholung
 Strukturierung
 Der Begriff des Control Flows, das Problem der Strukturierung mit Sprung
und Blockung
Kapitel 6
Algorithmentheorie
 Im vorangegangenen Kapitel wurde beschrieben, mit welchen
Elementen Algorithmen aufgebaut werden, und was man dabei zu
beachten hat. Dieses Kapitel geht nun darauf ein, ob ein Problem
überhaupt algorithmisch fassbar ist, ob eine gefundener Algorithmus
auch das tut was er soll und wieviel Zeit bzw. Platz er dafür benötigt.
 Inhalt
1. Berechenbarkeit
2. Korrektheit
3. Komplexität
Teile dieses Kapitels sind aus:
R.Manthey: Vorlesung Informatik 1, Uni Bonn, 2001
6.1
Berechenbarkeit
 Wir haben den Begriff und die Elemente eines Algorithmus vorgestellt
und Algorithmen zur Lösung von Problemen verwendet.
In diesem Unterkapitel werden nun einige Fragen zur Anwendbar- und
Sinnhaftigkeit von Algorithmen gestellt und beantwortet.
 Inhalt:
1.
2.
3.
4.
5.
6.
Einige Fragen
Das Entscheidungsproblem
Die Turing-Maschine
Berechenbarkeit
Rekursive Funktionen
Church‘sche These
H. Ernst:“Grundlagen und Konzepte der Informatik“,Vieweg-Verlag,2000
6.1.1 Einige Fragen
1. Kann jedes Problem durch einen Algorithmus beschrieben werden, d.h.
prinzipiell - bei genügender Sorgfalt - gelöst werden ?
2. Kann jeder Algorithmus in ein Programm übertragen werden ?
 Welchen Anforderungen muss eine Programmiersprache genügen, damit
jeder Algorithmus damit formuliert werden kann ?
3. Ist ein Computer grundsätzlich in der Lage, einen bekannten, als
Programm formulierten Algorithmus auszuführen ?
4. Ist ein solcher Computer formalisierbar ?




Wie sieht ein solches abstraktes Model aus ?
Gibt es genau ein Model oder mehrere ?
Sind diese Modelle äquivalent ?
Gibt es andere Modelle oder Beschreibungsformen, die diesem
formalisierten Computermodell entsprechen ?
 Frage 1 und Frage 4 sind wesentlich für den Begriff der
Berechenbarkeit, Frage 2 wird im anschließenden Kapitel behandelt,
Frage 4 ist Gegenstand der Vorlesung „Compilerbau“
6.1.2 Das Entscheidungsproblem
 Bis weit ins 20ste Jahrhundert war die Mehrzahl der Mathematiker
(insb. David Hilbert: 1862-1942) der Ansicht, dass man von jeder
Aussage algorithmisch beweisen könne, ob sie wahr oder falsch
sein.
 Anders ausgedrückt: Es sei entscheidbar, ob ein Problem lösbar oder
unlösbar ist.
 Die Frage, ob dies entscheibar ist oder nicht ging als Entscheidungsproblem in die Geschichte der Mathematik (und Informatik) ein.
 Kurt Gödel wies in seinem Unvollständigkeits-Theorem 1931 nach,
dass alle widerspruchsfreien axiomatischen Formulierungen der
Zahlentheorie unentscheidbare Aussagen enthalten.
 damit wurde insb. belegt, dass streng algorithmisch arbeitende
Computer prinzipiell nicht jedes Problem lösen können.
 Auf fast schon philosophischer Ebene wurde damit auch belegt, dass
Wahrheit eine andere Qualität als Beweisbarkeit besitzt.
 nicht alle „wahren“ Aussagen können auch bewiesen werden.
6.1.3 Die Turing-Maschine: Definition
 Als abstraktes Modell eines Computers beschrieb Alan Turing (19121954) 1963 - also noch vor der Erfindung des Digitalrechners - eine
nach ihm benannte abstrakte Maschine
 Formal kann eine Turing-Maschine wie folgt beschrieben werden:
 Alphabet: A = {a0, ... , an}, der Zeichenvorrat der Turing-Maschine, wobei
a0 das Leerzeichen ("blank") darstellt (Oft: a1=0, a2=1)
 Bandinschrift: B: Z  A eine Zuordnung, die jeder Stelle des rechtsseitig
unendlichen Bandes ein Zeichen zuordnet. Dabei wird festgesetzt, dass
B(k) = a0 für alle bis auf endlich viele .
 Kopfposition: k  Z
 Zustände: eine endliche Menge von Maschinenzuständen.Q = {q0, ..., qm}
Darunter sind q0, der Anfangszustand und H  Q , die Menge der
Haltezustände, ausgezeichnet.
 Statt Haltzustände wird oft auch eine Halteaktion angegeben
 Turing-Tabelle:
eine Übergangsrelation: d : A  Q  A  Q  {r, l, n, h}, das jedem
(gelesenen) Zeichen in Abhängigkeit eines Zustandes ein neues Zeichen,
einen Folgezustand und eine Aktion (r,l,n,h} zuordnet
6.1.3 Die Turing-Maschine: Programm
a1 a2 a3 a4 ... a6
falls
so ist
die
Maschine
im Zustand
q
das unter dem
Kopf gelesene
Zeichen
das neue
Zeichen
ak
al
die
Aktion
r oder l
der neue
Zustand
q‘
 Die Aktionen:
 r (right): das Verschieben des Kopfes nach rechts
 l (left): das Verschieben des Kopfes nach links
 optional n (none): keine Bewegung des Kopfes
 optional h (halt): Impliziter Übergang in einen Endzustand
6.1.3 Die Turing-Maschine: Beispiel
 Das „Busy beaver“-Problem:
Wieviele „1“-en kann ein terminierendes Touring-Programm auf einem
leeren Band mit einer vorgegebenen Anzahl von Zuständen maximal
erzeugen.
 In dieser Notation wird statt eines Übergangs in den Haltezustand (z.B. q5)
die Aktion „halt“ ausgeführt.
11 Schritte, 6 Einsen
96 Schritte, 13 Einsen
 Der Rekord für |Z|=5 liegt bei 4096 „1“en (J.Buntrock, H.Marxen, 1989)
 Es wurde gezeigt, dass es möglich ist, mehr als 4098 „1“en zu
generieren - allerdings nicht wie.
6.1.4 Definition: Berechenbarkeit
 Ein Problem ist genau dann algorithmisch lösbar, wenn es durch eine
Turing-Maschine darstellbar ist.
 Eine Funktion f(x) heißt berechenbar, genau dann wenn es einen
Algorithmus (eine Turing-Maschine) gibt, der bei gegebenem x das
Ergebnis f(x) liefert
 Ein Computer ist äquivalent zu einer universellen Turing-Maschine.
 d.h. ein Computer ist äquivalent zu einer Turing-Maschine, die jede
andere Turing-Maschine simulieren kann.
 Zur Simulation einer beliebigen Turing-Maschine muss auf dem
Eingabeband eine Beschreibung der zu simulierenden Maschine codiert
werden und außerdem deren Eingabeband gespeichert sein.
 Die Menge verschiedener universeller Turing-Maschinen ist abzählbar
- denn das Band ist binär codiert, jede Kombination lässt sich auf eine
natürliche Zahl abbilden. Die Menge aller Funktionen f(x) ist
überabzählbar (z.B. Funktionen die auf eine reelle Zahl abbilden) 
Es gibt (unendlich viele) nicht berechenbare Funktionen
6.1.5 Beispiel: Das Halteproblem
 Nicht berechenbare Probleme sind also keine Probleme, die noch
nicht gelöst sind, sondern solche, für die es keine Lösung gibt.
Das wohl bekannteste dieser Probleme ist das Halteproblem:
Es gibt kein Programm, das für ein beliebiges gegebenes Programm,
und für beliebige gegebene Eingabeparameter entscheidet, ob das
gegebene Programm anhält.
 Beweis:
Geg. Programm P mit Quelltext(P) als Eingabe
Annahme: Es gibt ein solches
Test(P)
Programm (Test)
Test(P)
y
P stoppt
mit P
Test1(P)
y
Test = ja
n
n
stoppe
ja
nein
Test(Test1)=ja  Test1(Test1) läuft endlos  Test(Test1)=nein Widerspruch !
6.1.6 Rekursive Funktionen
 Es gibt innerhalb der mathematischen Funktionen zwei Unterklassen:
 primitiv-rekursive Funktionen:
 jede primitiv-rekursive Funktion ist berechenbar
 es gibt berechenbare Funktionen, die nicht primitiv-rekursiv sind
 primitiv-rekursive Funktionen lassen sich genau mit Algorithmen ohne
Schleifenkonstrukte (aber mit Blockung) darstellen.
 -rekursive Funktionen
 jede -rekursive Funktion ist berechenbar
 es gibt berechenbare Funktionen, die nicht -rekursiv sind
 -rekursive Funktionen lassen sich mit Algorithmen mit Schleifenkonstrukte
(und Blockung) darstellen.
 Es gilt folgende Beziehung innerhalb von Funktionen:
berechenbare Funktionen
-rekursive Funktionen
primitiv-rekursive Funktionen
6.1.6 Church‘sche These
 Wir haben bislang verschiedene Äquivalenzen gefunden:
 Primitiv und -rekursive Funktionen sind Teilmengen von berechenbaren
Funktionen.
 Eine Funktion ist genau dann berechenbar, wenn es eine Turing-Maschine
zu deren Berechnung gibt,.
 Die Darstellung mit Hilfe einer Turing-Maschine ist äquivalent mit der einer
universellen Turingmaschinm, die wiederum eine Abstraktion eines
Computers darstellt
 Dies legt die Formulierung einer der Church‘schen These nahe:
Alle im intuitiven Sinn vernünftigen Formalisierungen von
Problemlösungen sind äquivalent
 Wenn ein Problem nicht durch eine Turing-Maschine gelöst werden kann,
so ist es algorithmisch überhaupt nicht lösbar
 Da Begriffe wie „intuitiv“ und „vernünftig“ nicht definiert sind, ist die
Church‘sche These nicht beweisbar.
6.2
Korrektheit
 Wir haben diskutiert, ob man jede (mathematische) Funktion berechnen
kann und haben dabei die Äquivalenz eines Algorithmus‘ mit
berechenbaren Funktionen gesehen.
In diesem Unterkapitel geht es nicht mehr nur darum, ob eine Funktion
berechenbar ist, bzw. ein Algorithmus für deren Berechnung existiert,
sondern ob der gegebene Algorithmus tatsächlich das macht, was er
machen soll
 Inhalt
1.
2.
3.
4.
5.
6.
7.
8.
U.Kastens:“Modellierung“, Vorlesung WS‘00/‘01, Uni Paderborn
Ansatz
Definition
Logik zur Verifikation (C.A.R. Hoare)
Regeln
Terminierung
Beispiele
Beweis des Euklid‘schen Algorithmus
Kritische Anmerkungen
6.2.1 Ansatz
 Wir haben zu Beginn des Kapitels den Begriff der Korrektheit definiert:
 partielle Korrektheit:
Jedes berechnete Ergebnis genügt der Ausgabespezifikation, sofern die
Eingaben der Eingabespezifikation genügt haben
 Terminierung:
Der Algorithmus hält nach endlich vielen Schritten mit einem Ergebnis an,
sofern die Eingaben der Eingabespezifikation genügt haben
 Zum Beweis der Korrektheit gehen wir also von der Eingabespezifikation aus und versuchen, mit den Aktionen (Statements) des
Algorithmus die Ausgabespezifikation abzuleiten.
 Die Eingabespezifikation wird dabei als Vorbedingung P(V) oder {P} und
die Ausgabespezifikation Q(V) oder {Q} als Nachbedingung mathematisch
formuliert
 Über die Aktionen des Algorithmus wird die Vorbedingung über
Zusicherungen Zi(V) zur Nachbedingung abgeleitet
 Also: P(V)  Z1(V)  ...  Zn(V)  Q(V)
6.2.2 Definition: Korrektheit
 Beispiel: Lösung der quadratischen Gleichung
qugl (IN: p,q: real, OUT x1,x2:real)
// Vorbedingung: (p*p)/4 > q
// Nachbedingung: x1 = (-b + sqr(p*p/4-q)) / (2*a) 
//
x2 = (-b - sqr(p*p/4-q)) / (2*a)
{
w : real;
w = sqr(p*p/4 - q);
x1 = -p/2 + w;
x2 = -p/2 - w:
}
 Ein Algorithmus heißt korrekt bezüglich seiner Spezifikation, wenn
für jeden Aufruf, der die Vorbedingung erfüllt, nach dem Aufruf des
Algorithmus‘ die Nachbedingung erfüllt ist (und er terminiert)
 Achtung:
Die Vorbedingung ist vom Aufrufer zu erfüllen, die Nachbedingung ist
durch den Algorithmus (bzw. den Implementierer) zu erfüllen.
6.2.3 C.A.R. Hoare: Logik zur Verifikation
 C.A.R. Hoare formulierte 1969 ein Kalkül zum Beweis von Aussagen
über Algorithmen und Programme
 damit sind - im Gegensatz zum Testes - statische Aussagen über Zustände
des Algorithmus ( Werte der Variablen) möglich. Diese Aussagen gelten für
alle Ausführungen des Algorithmus
 Durch logisch Schlüsse über die Elemente eines Algorithmus kann
gezeigt werden, dass
 an einer bestimmten Stelle im Algorithmus eine bestimmte Aussage gilt.
 eine Aussage an jeder Stelle eines Teils des Algorithmus invariant gilt
 Schleifen terminieren.
Also:
 ein Algorithmus aus jeder zulässigen Eingabe die geforderte Ausgabe
berechnet
6.2.3 C.A.R. Hoare: Beispiel
 min (IN: a,b: integer, OUT min:integer)
// Vorbedingung: a,b > 0 (nicht unbedingt notwendig)
// Nachbedingung: (min=a  min=b)  (mina)  (minb)
{
if a<b then {
//  Z1: a<b
min = a;
//  Z2: a<b  min=a  Z3: min=a  mina  minb
} else {
//  Z4: ba
min = b;
//  Z5: ba  min=b  Z6: min=b  minb  mina
}
//  Z7: (min=aminaminb)  (min=bminbmina)
//  Z8: (min=a  min=b)  (mina)  (minb) = Q
}
 Damit ist aus der Vorbedingung P mit Hilfe der Anweisung in min() die
Nachbedingung Q formal abgeleitet worden.
6.2.3 C.A.R. Hoare: Vorgehen
 Aussagen über den Algorithmenzustand, über Werte von Variablen
werden in den Algorithmus eingefügt:
 { P } A1 { Q } A2 { R }
 bedeutet: Q gilt immer zwischen der Ausführung von A1 und der
Ausführung von A2
 Beispiel: { i + 1  0} i := i + 1; { i  0 } a [i] := k; {...}
 Zur Verifikation eines Algorithmus muss für jede Anweisung S ein
Nachweis geführt werden:
 { Vorbedingung P } S { Nachbedingung Q }
 nachweisen: Wenn vor der Ausführung des Schrittes S die P gilt, dann
gilt Q nach der Ausführung von S, falls S terminiert.
 Beispiel: { i + 1  0} i := i + 1; {i  0} mit Zuweisungsregel nachweisen
 Die Aussagen werden entsprechend der Struktur von S verknüpft. Für
jede Anweisungsform wird eine spezielle Schlussregel angewandt.
 Die Spezifikation liefert Vorbedingung und Nachbedingung des
gesamten Algorithmus:
6.2.4 Regel: Zuweisung
 Die Zuweisung x = expr wertet den Ausdruck expr aus und weist das
Ergebnis der Variablen x zu.
Es gilt dann:
{P[x/expr]} x := expr {P}
oder
{P(x)} x = f(x) {P(f--1(x))}
 P[x/expr] steht für die Substitution von x durch expr in P
 Die Nachbedingung P erhält man dadurch, dass man jedes Vorkommen von
expr in der Vorbedingung durch x (die linke Seite der Zuweisung) ersetzt
 Wenn man also zeigen will, dass nach der Zuweisung eine Aussage P für x
gilt, muss man zeigen, dass vor der Zuweisung dieselbe Aussage P für expr
gilt.
 Beispiele:
 {a>0} x = a {x>0}
 {i+1>0} i=Succ(i) {i>0}: f(x)=Succ, f-1(x)=Pred(x), {P(Pred(x+1)}=(i+1-1>0)
 {i+1>0} i = i+1 {i>0}
6.2.4 Regel: Zuweisung - Beispiele
 {P[x/expr]} x := expr {P}
1. alle Aussagen der Vorbed. für expr, gelten für x in der Nachbedingung
2. Aussagen der Vorb. über x gelten in der Nachbedingung nicht mehr
3. Die Nachbedingung P erhält man dadurch, dass man jedes Vorkommen
von expr in der Vorbedingung durch x ersetzt
 ggf. ist die Vorbedingung so umzuformen, dass expr explizit Teil der
Vorbedingung ist (auf der linken Seite einer Aussage)
 „Alles was vorher für die rechte Seite der Zuweisung galt, gilt hinterher
für die linke - Alles was vorher für die linke galt, gilt nicht mehr - Alle
anderen Aussagen gelten weiterhin“
1.
2.
3.
4.
5.
6.
7.
{y=5}
{a>0  x>7}
{a>0  z>0}
{i+1>0}
{i0}  {i+1>0}
{i=2}  {i+1=3}
{z=5}
x=y
x=a
x=a
i=i+1
i=i+1
i=i+1
x=1
{x=5}
{x>0  x>7}
{x>0  z>0}
{i>0}
{i>0}
{i=3}
{z=5  x=1}
falsch wg. Punkt 2
z>0 ist nicht betroffen
passend umformen
passend umformen
z nicht betroffen, x neu
6.2.4 Regel: Konsequenz
 Abschwächung der Nachbedingung
wenn gilt
{P} S {R}
Beispiel
{a+b>0} S {x>0}
und
{R}  {Q}
dann gilt auch
{P} S {Q}
{x>0}  {X0}
{a+b>0} S {X0}
 Verschärfung der Vorbedingung
wenn gilt
und
dann gilt auch
{P}  {R]
{R} S {Q}
{P} S {Q}
 Beispiel (Notation: Im Algorithmus können Implikationen in
Ausführungsrichtung eingefügt werden)
{a+b>0}
x = a+b;
{x>0}  {2*x  0}
y = 2 * x
{y0}
6.2.4 Regel: Sequenz
 Folgendes Schema lässt sich auf eine Sequenz von Aktionen
(Statements) anwenden:
wenn gilt
{P} S {R}
und
{R} S2 {Q}
dann gilt auch
{P} S1,S2 {Q}
{a>0  y>0}
b = y;
{a>0  b>0}
{x>0  y>0}
a = x;
{a>0  y>0}
b = y;
{a>0  b>0}
 Beispiel:
{x>0  y>0}
a = x;
{a>0  y>0}


 Bei trivialen Ableitungen können die Zwischenschritte (Zusicherungen,
Aussagen) demnach auch weggelassen werden:
{x>0  y>0}
a = x; b = y;
{a>0  b>0}
6.2.4 Regel: Bedingte Anweisung
 Schema:
wenn gilt
{P B} S {Q}
und
{PB}  {Q}
dann gilt auch
{P} if B then S {Q}
 Um die Nachbedingung einer bedingten Anweisung zu beweisen, muss
1. aus der Vorbedingung und der Anweisungs-Bedingung über die Anweisung
die Nachbedingung nachgewiesen werden
2. aus der Vorbedingung und der Negation der Anweisung die
Nachbedingung direkt folgen
 Beispiel:
 Gegeben: if a<0 then a = -a
 Beweise, dass der Algorithmus a0 für alle a liefert:
1. {P  a<0}  {P -a>0} a=-a {P  a>0}  {P  a 0}
2. {P  (a<0)}  {P  a 0}
dann gilt auch
{P} if a<0 then a=-a {P  a 0}
6.2.4 Regel: Bedingte Anweisung - Notation
 Beispiel:
 Gegeben: if a<0 then a = -a
 Beweise, dass der Algorithmus a0 für alle a liefert:
1. {P  a<0}  {P -a>0} a=-a {P  a>0}  {P  a 0}
2. {P  (a<0)}  {P  a 0}
dann gilt auch
{P} if a<0 then a=-a {P  a 0}
 Notation:
{P}
if a<0 then
{P  a<0}  {P -a>0}
a = -a
{P  a>0}  {P  a 0}
// leere Alternative:
{P  (a<0)}  {P  a 0}
{P  a 0}
6.2.4 Regel: Einfache Alternative
 Schema:
wenn gilt
{P B} S1 {Q}
und
{PB} Ss {Q}
dann gilt auch
{P} if B then S1 else S2 {Q}
 Aus der gemeinsamen Vorbedingung P muss für beide Alternativen
dieselbe Nachbedingung Q nachweisbar sein
 Beispiel: Gegeben: a>0, b>0, ab und ein Algorithmus (s.u)
 Beweise, dass nach den Operationen immer noch gilt: a>o, b>0
{a>0  b>0  ab}
if a>b then
{a>0  b>0  ab  a>b}  {b>0  a-b>0}
a = a-b;
{b>0  a>0}
else
{a>0  b>0  ab  ab}  {a>0  b-a>0}
b = b-a;
{a>0  b>0}
{a>0  b>0}
6.2.4 Regel: Schleife
 Schema:
wenn gilt
{P  I B} S {I}
dann gilt auch
{I} while B { S } {I  B  Q}
// I = Schleifeninvariante
 Schleifeninvarianten sind Zusicherungen in Schleifen, die beim
Durchlaufen des Schleifenkörpers erhalten bleiben. Es gelte





P
Q
I
B
S
Zusicherung über Variable vor Schleifeneintritt
Zusicherung über Variable nach Schleifenende
Schleifeninvariante
Wiederholbedingung der Schleife
Statements (Aktionen) im Schleifenkörper
 Die Nachbedingung einer Schleife ist über die Invariante
nachgewiesen, wenn gilt:
1. P  I
die Invariante muss vor Schleifeneintritt wahr sein
2. (I B)  I
die Invariante darf in Schleife nicht verändert werden
3. (I B)  Q die Nachbedingung muss sich nach Verlassen der
Schleife aus der Invariante nachweisen lassen
6.2.4 Regel: Schleife - Schema
 Das Schema der Gültigkeit von Aussagen sei anhand des
Flussdiagramms für Schleifen verdeutlicht:
P

I muss aus
P ableitbar
sein
Um Q(V) zu beweisen, muss
man I(V) so wählen, dass
Q(V) aus I(V)  B(V) ableitbar
ist
I
I  B
B?
w

Q(V)
f
IB

S
I
Hier muss man beweisen,
dass sich I in S aus I  B
ableiten lässt
6.2.4 Regel: Schleife - Beispiel
 Algorithmus zum Potenzieren
// Vorbedingung: b  0 (positive Exponenten)
P
// Nachbedingung: z = ab
x=a, y=b, z=1;
{ x=a, y=b, z=1; y  0}
I
y
{INV: z * x = ab  y0}
while y>0
I  B Q
{
B?
{ INV  y>0  z*x(y-1)+1=ab  (y-1)+1 > 0 }
f
y = y-1;
w
y+1
IB
b
{ z*x =a  y+1>0 } 
{ ((z*x)/x)*xy+1 = ab  y  0 }
z = z*x;
S
y+1
b
{ z/x*x
= a  y  0 } 
I
{ z * xy = ab  y  0
 INV }
}
{ INV  B  z * xy = ab  y0  y0  z*x0 = z = ab  Q }
6.2.4 Regel: Schleife - Schleifeninvariante
 Das Finden der „richtigen“ Invariante kann ganz schön kniffelig sein:
 Ein paar „Tips“:
 Wenn die Nachbedingung nicht gegeben ist, versuche die Semantik des
Algorithmus‘ zu verstehen, z.B. anhand von Beispielen.
 Betrachte die Anweisungen in der Schleife:
Meist wird etwas vergrößert (z.B. die Variable der Abbruchbedingung),
während etwas anderes verkleinert wird - oder umgekehrt. Kombiniere
diese:
z * xy
 Setze Ein- und Ausgabevariablen in Bezug zueinander
z * xy = ab
 Verwende die Schleifenbedingung zum „Einklemmen“ der
Schleifenvariable.
 Beachte, dass aus INV und B(V) Q(V) ableitbar sein soll Das
bedeutet, dass man die Invariante aus der Nachbedingung konstruieren
kann, indem man die negierte Bedingung mit berücksichtigt
z * xy = ab  y=0  z*x0 = z = ab  Q
6.2.5 Terminierung
 Die Terminierung einer Schleife muss separat nachgewiesen werden
 Beweis der Terminierung
1. Gib einen ganzzahligen Ausdruck E an über Variablen, die in der Schleife
vorkommen und zeige, dass E bei jeder Iteration durch S verkleinert wird
2. Zeige, dass E nach unten begrenzt ist, z.B. dass 0E eine Invariante der
Schleife ist
3. Zeige, dass die Grenze auch erreicht wird.
 E kann auch monoton vergrößert und nach oben begrenzt sein
 Beweis der Nicht-Terminierung: Beweise,
1. dass RB eine Invarianz der Schleife ist (also R in die Schleife geht) und
dass es eine Variablenbelegung gibt, so dass RB vor der Schleife gilt
2. dass R einen speziellen Zustand charakterisiert, in dem die Schleife nicht
anhält
 Es gibt Schleifen, für die man nicht entscheiden kann, ob sie für jede
Vorbedingung terminieren.
6.2.5 Terminierung - Beispiele
 { a>0  b>0 }
while ab {
while a>b { a=a-b }
while a<b { b=b-a }
} // terminiert
 { a>0  b>0 }
while ab {
while ab { a=a-b }
while a<b { b=b-a }
} // terminiert nicht immer (a = 2*b)
 { nN  n>1 }
while n>1
if n gerade then
n = n/2
else
n=3*n+1 // Terminierung unbewiesen
6.2.6 Beispiel: Multipl. durch fortgesetze Addition
// Vorbedingung P: a0  b0, Beh.: Nachbedingung Q: z = a*b
x = a; y = b; z = 0; { x0  b0  z=0 }
// Auch hier: Die Summe von x*y+z bleibt konstant a*b
{ INV: z+xy = ab, x,y0 }
while x > 0 {
P
{ INV  x>0 } 
{ (z+y)-y+xy = ab, x>0,y0 }
I
z = z + y;
I  B Q
{ z-y+xy
= ab, x>0,y0 } 
B?
f
{ z-y+((x-1)+1)y
= ab, (x-1)+1>0,y0 }
w IB
x = x - 1;
S
{ z-y+(x+1)y
= ab, x+1>0,y0 } 
{ z-y+xy+y
INV
= z+xy = ab, x,y0 } 
}
{ INV  B = (z+x*y=a*b)  (x=0)  z+0*y=a*b  Q }
I
6.2.6 Beispiel: Die ägyptische Bauernmultiplikation
// Vorbedingung P: a0  b0, Beh.: Nachbedingung Q: z = a*b
x = a; y = b; z = 0; { x,y0  z=0  x=a  y=b }
// Schleife verdoppelt x und halbiert y: Invariante:
 INV
INV = { z+x*y = a*b  x,y0 }
while x > 0 {
{ INV  x>0 }
if (odd(x) then
{ (z+y)-y+x*y = a*b)
 x>0,y0 }
z = z+y;
{ odd(x)  z-y+x*y = a*b  x>0,y0 }
// leere Anweisung { even(x)  z+x*y
= a*b  x>0,y0 }
{ ( odd(x)  z-(2y/2)+x*(2y/2) = a*b  x>0,(2y/2)0 ) 
( even(x)  z+x*(2y/2)
= a*b  x>0,(2y/2)0 )
}
y = y * 2;
{ ( odd(x)  z-y/2+x*y/2 = a*b  x>0,y/20 ) 
( even(x)  z+x*y/2
= a*b  x>0,y/20 )
} 
{ (odd(x)  z-y/2+(2(x div 2)+1)*y/2 = a*b  (2(x div 2)+1)>0,y0 ) 
(even(x)  z+(2(x div 2))*y/2
= a*b  2(x div 2) >0,y0 ) }
x = x div 2; // div = Ganzzahldivision
{ ( odd(2x+1)  z-y/2+(2x+1)*y/2 = a*b  (2x+1)>0,y/20 ) 
( even(2x)  z+
2x
*y/2 = a*b  2x
>0,y/20 )
}
{ (z-(y - y(2x+1))/2 = z-(y-2xy-y)/2 = z-(-2xy/2)= z+xy = a*b )
(z
+ 2x * (y*2)
= z+xy = a*b )}INV
} { INV  B = (z+x*y=a*b)  (x=0)  z+0*y=a*b  Q }
6.2.7 Kritische Anmerkungen
 Die Verifikation entspricht einer mathematischen Beweisführung und
kann entsprechend kniffelig, aufwändig, wenn nicht gar unmöglich sein.
 Durch formale Überprüfung der Korrektheit, lassen sich Schlüsselstellen
eines Algorithmus‘ (eines Programmes) verifizieren
 Durch das Denken mit Zusicherungen, Invarianten und mathematische
Folgerungen wird die Erstellung fehlerfreier Programme gefördert.
 Auch wenn es semi-automatische Systeme zur formalen Verifikation
von Algorithmen gibt, ist es praktisch nicht möglich, auch nur halbwegs
komplexe Programmsysteme damit zu verifizieren
 Selbst wenn es möglich wäre, Algorithmen vollständig formal zu
beweisen, so wäre dies keine Garantie, dass ein Programmsystem
entsprechend den Wünschen eines „Kunden“ funktioniert. Dazu
gehören alle Mechanismen eines ordentlichen Software-Engineerings.
6.3
Komplexität
 In diesem Kapitel haben wir den Begriff „Berechenbarkeit“ definiert als
all das, was algorithmisch beschreibbar ist. Wir haben eine Methode
vorgestellt, mit der man (meist) zeigen kann, dass ein Algorithmus das
tut was er soll. Was noch fehlt - und hier behandelt werden soll - ist die
Frage nach dem Zeit- und Platzbedarf eines Algorithmus.
 Inhalt
1.
2.
3.
4.
5.
6.
Wie „gut“ ist ein Algorithmus
Die O-Notation
Häufige O-Ausdrücke
Einige Regeln
Quantitatives
Platzbedarf
6.3.1 Qualität eines Algorithmus
 Die Abarbeitung eines Algorithmus benötigt „Resourcen“, vor allem:
 Zeit
 Platz
Laufzeit des Algorithmus
Speicherplatzbedarf des Algorithmus
 Problem bei der Resourcenermittlung - der Resourcenbedarf ist
Abhängig von:





der Problemgröße (z.B. Multiplikation einer 10x10 bzw. 100x100 Matrix)
der Eingabewerte (z.B. Sortieren einer bereits sortierten Menge)
der Fragestellung (bester, mittlerer, schlechtester Fall)
der Güte der Implementierung (z.B. (un)geschickte Typwahl)
der Hard- und Software (z.B. Schneller Rechner, optimierter Compiler)
 Es gibt auch Qualitätsmerkmale eines Algorithmus, der sich nicht am
Resourcenbedarf festmachen (aber das ist eine andere Geschichte ...)
 Wartbarkeit
 Robustheit
 „Eleganz“
...
6.3.2 Die O-Notation: Definition
 Definition:
Eine Funktion g(n) wird O(f(n)) genannt („Die Laufzeit, der Aufwand,
die Zeitkomplexität von g(n) ist O(f(n))“), falls es Konstanten c und n0
gibt, so dass:
g(n)  cf(n), für fast alle n > no ist
 f(n) ist damit eine obere Schranke für die Laufzeit des Algorithmus
(allerdings nur ab einem bestimmten c und n0)
 Beispiel:
 Bei der Analyse eines Algorithmus hat sich herausgestellt, dass die Laufzeit
g(n) = 3n2 + 7n - 1 ist.
 Behauptung: Die Laufzeit von g(n) ist O(n2), also f(n)=n2,
 Beweis:
Es muss Konstanten c und n0 geben, so dass gilt
3n2+7n-1  c n2, für alle n > n0
setze n0=7 und c=4, dann gilt: 3n2+7n-1  3n2+7n  3n2+n2 = 4n2
6.3.2 Die O-Notation: Schranken
 Die Notation gibt nur eine obere Schranke der Komplexität , das muss
nicht notwendigerweise die beste Schranke sein.
 Beispiel:
Eine weitere obere Schranke für g(n) = 3n2 + 7n - 1 ist auch O(n3), welche
sicher nicht die beste ist.
 Bei der Suche nach der Größenordnung von f(n) wird man versuchen,
das kleinste f(n) zu finden, für das g(n) < c . f(n)
Dieses ist dann eine kleinste, obere Schranke für den Aufwand
 Zur Bestimmung des tatsächlichen asymptotischen Aufwands wird
man also noch eine größte, untere Schranke h(n) = (g(n)) suchen für
die gilt:
limn h(n)/f(n) = 1
 Eine untere Schranke ist die Zeit, die jeder Algorithmus (ab einem n>n0)
benötigt
 Das ist im Allgemeinen viel schwieriger !
6.3.2 Die O-Notation: Achtung
 Achtung !
Die Konstanten c und n0 werden üblicherweise nicht angegeben und
können sehr groß sein
 Beispiel:
Algorithmus A habe eine Laufzeit von O(n2)
Algorithmus B für das gleiche Problem eine Laufzeit von O(1,5n)
Welcher Algorithmus ist besser ?
 schnelle Antwort: A (das stimmt auch für große n)
 bessere Antwort: Wie groß ist n ? Wie groß sind die Konstanten ?
 z.B. für cA=1000 und cB=0,001
Bis hier ist B besser als A
n
cAn2
cB1,5n
1
10
20
50
100
103
105
4  105
2,5  106
107
1,5  10-3
1,8  10-2
3,3
6,4  105
4,1  1014
6.3.3 Häufige O-Ausdrücke: O(1)
 Teile von Ausdrücken, die eventuell ein „paar“ Mal durchlaufen werden,
wobei die (maximale) Anzahl der Durchläufe nicht abhängig von den
Eingabewerten sind, haben konstante Laufzeit: O(1)
 Beispiel:
max, i, y : integer;
max = 0;
y << Tastatur;
if (y < 20) then max=10
else
max=100;
for i=1 to max
{
y = y+1;
}
 Die Anzahl der Schleifendurchläufe ist zwar abhängig von y (entweder 20
oder 100), die maximale Anzahl aber nicht (immer 100, egal wie groß oder
klein y ist)
6.3.3 Häufige O-Ausdrücke: O(log n) - rekursiv
 Rekursive Algorithmen, die in jedem Schritt die Menge der Eingabedaten
halbieren haben eine Laufzeit von O(log n)
 eigentlich O(ld n), aber da ld n  3,322 log b = c log b ist O(ld b)=O(log n)
 Beispiel: Suche in einem sortierten Binärbaum
search (IN: x:integer; tree:*node; OUT: found:boolean)
{
if tree == nil then
{ // there is no tree to search => x not found
found = false;
return;
// ATTENTION: return already here
}
if (x < node.value) then
search(x,node.left, found)
else
if (x > node.value) then
search(x,node.right,found)
else if (n == node.value)
found=true;
}
6.3.3 Häufige O-Ausdrücke: O(log n) - Zeitbedarf
 Block mit rekursivem Aufruf der/s halben Eingabemenge/-Wertes
rek_block (IN: Eingabemenge OUT: Ausgabewert) {
if ( Trivialfall) then {
Ausgabewert = Trivialwert
}
// optional: Aktionen mit konstantem Aufwand
rek_block (Eingabemenge / 2);
}
 Bestimmung des Zeitbedarfs
 Der Zeitbedarf für das Durchlaufen ergibt sich aus:




Abfrage des Trivialfalls und (optional) Aktionen  O(1)
Rekursiver Aufruf mit Eingabemenge/Wert die/der halb so groß ist, also n/2.
also : Tn = 1 + Tn/2 (Tn = Zeitbedarf für n, n2)
T1= 0 (eigentlich 1, kann aber vernachlässigt werden)
 Annahme (o.B.d.A.): Eingabemenge/-wert ist Potenz von 2 also n = 2k,
 Diese Annahme kann man machen, denn falls n keine Zweierpotenz ist, erhöht
man die Eingabemenge/-wert auf die nächste 2er Potenz und bekommt noch
immer eine obere Schranke.
 T2k = T2k-1 +1 = T2k-2 +1+1 = ... = T20 + k = k  T2k = k  Tn= k = ldn
6.3.3 Häufige O-Ausdrücke: O(n) - rekursiv
 Rekursive Algorithmen, die in jedem Schritt die Menge der Eingabedaten
halbieren aber dazu jedes Element betrachten müssen haben eine
Laufzeit von O(n)
 Beispiel: Suche in einer sortierter Liste (array) mit 0 am Ende
search (IN: x:integer; list:*liste; OUT: found:boolean) {
i : integer;
if (list[1]==0) then found = false; // list with no element
i=1; while (list[i] <> 0) i=i+1
// get length of list
if (x==list[i/2]) then found = true;
else
if (x<list[i/2]) then {
list[i/2+1]=0; search(x,&list[1],found} };
else
search(x,&list[i/2+1],found);
}
 Zeitbedarf: Tn = Tn/2+ n (Tn = Zeitbedarf für n, n2, T1=0)
Annahme (o.B.d.A.): n = 2k,
T2k = T2k-1 + n = T2k-2 + n/2+n = ... = T20 +n/2+n/4 + ... + 0 = 2n-2 O(n)
6.3.3 Häufige O-Ausdrücke: O(n) - iterativ
 Iterative Algorithmen die eine lineare Liste durchlaufen deren Länge
abhängig von der Menge der Eingabeelemente ist (einfache Schleife),
haben die Laufzeit O(n)
 Beispiel: Suche in einer sortierter Liste (array) mit 0 am Ende
search (IN: x:integer; list:*liste; OUT: found:boolean) {
i : integer;
found = false; // initialize OUT-value
i=1;
while ((list[i] <> 0) and (not found)) {
i=i+1;
if (list[i]==x) then found = true;
}
}
 Anmerkung:
 Dieser Algorithmus funktioniert auch mit unsortierten Listen
 Warum dann einen rekursiven, teilenden Algorithmus ?
 Anzahl „eingeschränkter“ Vergleiche O(n)
 Anzahl „vollständiger“ Vergleiche O(log n)
6.3.3 Häufige O-Ausdrücke: O(n) - rekursiv
 Rekursive Algorithmen, die die Eingabedaten in zwei Hälften aufspalten,
und beide Hälften getrennt abarbeiten, haben eine Laufzeit von O(n)
 Beispiel: Erstellen eines „Lineals“ (siehe auch: Skript Dr. Geisse)
linael (IN: links,rechts,höhe:integer) {
mitte : integer;
if (höhe>0) then {
mitte = (links + rechts) / 2;
zeichne (mitte,höhe);
lineal (links,mitte,höhe-1);
lineal (mitte,rechts,höhe-1); }
}
 Zeitbedarf: Tn = 2Tn/2+ 1 (Tn = Zeitbedarf für n, n2, T1=0)
Annahme (o.B.d.A.): n = 2k,
T2k = 2T2k-1 + 1  1/2 T2k = T2k-1 + 1/2 = 2T2k-2 + 1 + 1/2 
1/4 T2k = T2k-2 + 1/2 + 1/4
 ... 
1/2k T2k = T20 + 1/2 + 1/4 + ... + 1/2k = 1 - 1/2k
 T2k = 2k-1  Tn = n-1  Laufzeit O(n)
6.3.3 Häufige O-Ausdrücke: O(n log n)
 Rekursive Algorithmen, die die Eingabedaten in zwei Hälften aufspalten,
und die Eingabedaten einmal durchlaufen (davor, währenddessen, oder
danach), haben eine Laufzeit von O(n log n)
 Beispiel: Sortieren einer Liste a : array[1..max] of integer (C.A.R. Hoare)
Quicksort (IN:l,r:integer) {
// l left, r right index
i,j,x : integer; // i,j: indexes, x,y: elemets
i=l; j=r;
// initialize i with left, j with right index
x = a[(l+r)/2}] // get element in the middle
do { // walk with i from left, with j from right
while a[i]<x { i=i+1 }
// skip smaller elements from left
while a[j]>o { j=j-1 }
// skip larger elements from right
if (i<=j) then { exchange(a[i],a[j]); i=i+1; j=j11 }
} while i<=j // i is now right of j -> stop loop
if l<j then sort(l,j);
// sort left part (only if exists)
if i<r then sort(i,r);
// sort right part (only if exists)
 Zeitbedarf: Tn = 2Tn/2+ n (Tn = Zeitbedarf für n, n2, T1=0)
Annahme (o.B.d.A.): n = 2k, (d.h. k = ld n)
T2k = 2T2k-1 + 2k  1/2k T2k = T2k-1/2k-1 + 1 = T2k-2/2k-2 + 1 + 1 = ... = k
 1/2k T2k = k
 T2k = 2k k  Tn = n log n  Laufzeit O(n log n)
6.3.3 Häufige O-Ausdrücke: O(n2) - rekursiv
 Rekursive Algorithmen, die die Eingabedaten jeweils um eins verringern,
dabei aber alle Daten betrachten müssen, haben eine Laufzeit von O(n2)
 Beispiel: Sortieren einer Liste a : array[1..max] of integer
StraightSelection (IN:l,r:integer) { // l left, r right index
i: integer;
// index
i = l;
// start with left element
while (i<r) {
// walk through complete list
// if an element is smaller, bring it to the left
if (a[i]<a[l]) then exchange(a[i],a[l]);
i = i+1;
}
if (l<r) then StraightSelection (l+1,r);
}
 Zeitbedarf: Tn = Tn-1+ n (Tn = Zeitbedarf für n, n2, T1=1)
Tn = Tn-1 + n = Tn-2 + n-1 + 1 = Tn-3 + n-1 + n-2 + 1 = ... = 1+2+3+..+n
 Tn = (n(n+1))/2 = 1/2n2 + 1/2n  Laufzeit O(n)
6.3.3 Häufige O-Ausdrücke: O(n2), O(n3) - iterativ
 Iterative Algorithmen die eine Liste - deren Länge abhängig von der
Menge der Eingabeelemente ist - (fast) sooft durchlaufen, wie die Liste
lang ist (doppelt verschachtelte Schleife), haben die Laufzeit O(n2)
 Beispiel: Sortieren einer Liste a : array[1..max] of integer
StraightSelection (IN:l,r:integer) { // l left, r right index
i: integer;
// index
i = l;
// start with left element
for i=1 to r-1
// walk through complete list
{
for j=i+1 to r // walk through rest of list
{
if (a[j]<a[i]) then exchange(a[i],a[j]);
}
}
}
 Dreifach verschachtelte Schleifen haben eine Laufzeit von O(n3)
 Beispiel: Multiplikation zweier Matrizen
6.3.4 Einige Regeln
 Hat ein Algorithmus eine Laufzeit, die mit einem Polynom k-ten Grades
darstellbar ist (aknk + ak-1nk-1 + ... + a0) , so ist die Laufzeit O(nk)
 Beispiel:
Laufzeit: 9n3 + 7n - 1000  Laufzeit O(n3)
 Wird ein Teil A mit Laufzeit O(x) vor einem Teil B mit Laufzeit O(y)
ausgeführt, so ist die Gesamtlaufzeit das Maximum der Laufzeiten.
 Beispiel:
Laufzeit A ist O(n2), Laufzeit B ist O(n)
 Laufzeit A,B = O(n2) + O(n) = O(n2)
 Wird ein Teil A mit Laufzeit O(x) innerhalb eines Teiles B mit Laufzeit
O(y) ausgeführt, so ist die Gesamtlaufzeit das Produkt der Laufzeiten.
 Beispiel:
 Beispiel:
Laufzeit A ist O(n2), Laufzeit B ist O(n)
 Laufzeit A(B) = Laufzeit B(A) = O(n2)  O(n) = O(n3)
Eine Dreifach verschachtelte Schleife (O(n3)) ist eine
Schleife O(n) in einer zweifach verschachtelten
Schleife (O(n2)) : O(n3) = O(n2)  O(n)
6.3.5 Quantitatives
n
ld n
(ld n)2
n
10
100
1000
10000
100000
1000000
3
6
9
13
16
19
9
36
81
169
256
361
3
10
31
100
316
1000
n ld n
n2
30
100
600
1000
9000 1000000
130000
108
1,6 106
1010
19 106
1012
6.3.6 Platzbedarf
 Unter „Aufwand“ wird i.A. der zeitliche Aufwand, also die
Zeitkomplexität verstanden
 Manchmal ist auch die Platzkomplexität bzw. Speicherbedarf
relevant.
Darunter versteht man dann, ganz entsprechend zur Zeitkomplexität,
eine obere Schranke für den Speicherbedarf eines Algorithmus für ein
Problem mit einer Eingabemenge der Größe n.
 Auch beim Speicherbedarf von Algorithmen existieren die
„Komplexitätsklassen“ (n, n2, n log n, ...)
 Auch beim Speicherbedarf unterscheiden sich „geschickte“ und
„ungeschickte“ Algorithmen für die Lösung eines gegebenen Problems.
 Da Computerspeicher endlich, die Zeit aber potentiell unendlich ist hat
der Speicherbedarf oft die höhere Priorität.
 Meist wird daher der Algorithmus gewählt, der sehr Nahe am minimal
möglichen Speicherbedarf bei möglichst optimalem Aufwand liegt.
6.3.6 Platzbedarf
 Oft kann man eine bessere Zeitkomplexität zu Lasten des
Speicherbedarfs erreichen (und umgekehrt)
 Beispiel: Trivialer Hashsort (Unsortierte Liste a: array [1..n] of type)
b: array [1..max(type)]
// max(type) is largest element in type,
// e.g. max(unsigned integer) = 65535
i,j : integer;
for i=1 to n {
b[a[i]] = a[i];
}
j = 1;
for i=1 to max(type) { // shift to beginning of list
if ((not_empty(b[i])) and (i<>j)) then
{ b[j]=b[i]; j=j+1;}
}
 1.Schleife + 2.Schleife: O(n) + O(1) = O(n)
 Man wägt daher Speicherbedarf und Zeitkomplexität gegeneinander ab.
6.4
Zusammenfassung des Kapitels
 Berechenbarkeit:
1. Einige Fragen und das Entscheidungsproblem
2. Die Turing-Maschine und der Begriff der Berechenbarkeit
3. Rekursive Funktionen und die Church‘sche These
 Korrektheit
1.
2.
3.
4.
Ansatz und Definition
Logik zur Verifikation: Die Hoare‘schen Regeln
Beispiele und Beweis des Euklid‘schen Algorithmus
Kritische Anmerkungen
 Komplexität
1.
2.
3.
4.
Wie „gut“ ist ein Algorithmus und die O-Notation
Häufige O-Ausdrücke und einige Regeln bei deren Anwendung
Quantitatives
Platzbedarf
Kapitel 7
Sprachen
 Wir haben Information als grundlegenden Begriff der Informatik
eingeführt und über Codes und Datenstruktur abstrahiert.
Andererseits haben wir den Umgang mit Information, zunächst am
einfachen Beispiel (Rechnen mit Zahlen in beliebigen Zahlensystemen),
dann abstrakter und mächtiger mit Hilfe von Algorithmen kennengelernt.
Dieses Kapitel führt nun in die wesentliche Anwendung dieser
grundlegenden Überlegungen ein. Es beschreibt die fundamentalen
theoretischen Grundlagen von Sprachen im Allgemeinen und
Programmiersprachen im Besonderen.
 Inhalt
1.
2.
3.
4.
5.
Programmiersprachen
Syntax und Semantik
Reguläre Ausdrücke
Endliche Automaten
Grammatiken
7.1
Programmiersprache
 Programmiersprachen sind das Mittel der Informatik, Algorithmen
problemorientiert zu formulieren.
Die wichtigen Begriffe „Programmiersprache“ und „Programm“ sind
dabei - zumindest was den zweiteren betrifft - nicht ganz klar und sollen
zunächst kurz eingeführt werden. Danach soll ein sehr kurzer Überblick
über die Entwicklung von Programmiersprachen gegeben werden, der
mit einem Resumée abschließt.
 Inhalt
1.
2.
3.
4.
Was ist eine Programmiersprache
Was ist ein Programm
Generationen von Programmiersprachen
Programmiersprachen heute
7.1.1 Was ist eine Programmiersprache
 Eine Programmiersprache ist eine künstliche Sprache zur präzisen
Formulierung von Algorithmen.
Sie ist:
 vollständig (zumindest in einigen Aspekten)
 eindeutig
 maschinell verarbeitbar
 Die Programmiersprache spielt eine Mittlerrolle zwischen Mensch und
Maschine
 Beschreibung soll für den Menschen generierbar und verständlich sein
 Beschreibung soll für die Maschine verständlich und exakt, wiederholbar
ausführbar sein.
 Programmiersprachen sind abhängig von
 Anwendungsgebiet
 Art der Rechnersysteme
 Mentalität der Programmierer
7.1.2 Was ist ein Programm
 Ein Programm durchläuft einige Repräsentationsformen
 Quelltext
 Der Quelltext ist die dem Menschen geläufigste Repräsentationsform eines
Programmes.
 Der Quelltext wird meist vom Menschen mit einem Editor erstellt und
formalisiert einen Algorithmus
Teilweise wird Quelltext auch von anderen Programmen generiert
 Der Quelltext eines Programmes befindet sich oft in genau einer Datei,
in größeren Programmen meist in mehreren Dateien
 Objektmodul
 Wird ein Programm z.B. mit Hilfe eines Compilers übersetzt, so ist es bereits in
binärer Repräsentation, allerdings so noch nicht lauffähig auf einem Prozessor
 Ausführbares Programm
 Das Programm ist binär repräsentiert und mit allen Teilen „zusammengebunden“, die notwendig für die Ausführung auf einem Prozessor sind.
 Prozess
 Ein Prozess ist ein Programm, welches gerade auf dem Prozessor (auf den
Prozessoren) ausgeführt wird.
7.1.3 Generationen von Programmiersprachen
1. Generation: Maschinensprachen
2. Generation: Assemblersprachen
Wie ?
Speicherstelle
3. Generation: Prozedurale Sprachen
Relation
4. Generation: Datenbankabfragesprachen
Objekt
5. Generation: Deklarative Sprachen
Was ?
7.1.3 Generation: 1. Maschinensprachen
 Prozessorspezifische Sprache, meist in Binärform :
0100 0111 0110 0110
0011 0111 0111 0000
1100 1000 0010 1000
0111 0100 0000 0000
...
 Direkte Ausführung durch Prozessor möglich
 Extrem aufwendige Programmierung
 Einsatz heute nur noch
 in (manchen) Mikroprozessorsteuerungen
 im ROM-BIOS, Bootblock
 zur Wartung alter Steuergeräte, wenn deren Einsatz bzgl. des
Programmieraufwandes noch lohnend ist
7.1.3 Generation: 2. Assemblersprachen
 Verwendung mnemonischer Bezeichner, strukturäquivalent zu
Binärcode (seit ca. 1950)
00401571
00401579
00401584
00401586
00401588
0040158E
00401592
0040159B
0040159D
0040159F
004015A7
...
mov
test
jne
push
call
pop
ret
mov
push
call
ret
ecx,dword ptr [esp+4]
ecx,ecx
0040158E
0FDh
dword ptr ds:[4010B8h]
ecx
8
esi,ecx
0
0040156C
 Übersetzung des Codes durch Assembler
 Einsatz heute noch bei systemnaher Programmierung
7.1.3 Generation: 3. Prozedurale Sprachen
 Prozedurale Sprachen setzen Algorithmen und Datenstrukturen, wie sie
in den vorangegangenen Kapiteln beschrieben wurden sehr natürlich
um.
 Rechnerunabhängige Sprachen in einer meist anwendungsabhängigen
Schreibweise (Syntax) und Bedeutung (Semantik).
Fortran
Cobol
Algol
PL/1
Basic
Pascal
Chill
Pearl
C
Ada
Modula
C++
1954
1957
1957
1960
1963
1968
1968
1970
1970
1975
1975
1980
wissenschaftlich/technisch
kommerziell
wissenschaftlich/technisch
universell
einfach wissenschaftlich/technisch
universell, Lehre
Systemprogrammierung (T-Kom)
Regelung
universell, Systemprogrammierung
universell, Militär
Lehre
universell, Systemimplementierung
7.1.3 Generation: 4. Datenbankabfragesprachen
 Einfacher Umgang mit Datenbanken (4GL, seit 1965):
 Definition des Datenbank-Layouts
 Operationen auf Datenbanken
 Generierung von graphischen Benutzeroberflächen
 Beispiele:
 SQL (Standard Query Language)
 NATURAL
 Heute oft
 in Kombination mit prozeduralen Sprachen
 unterstützt durcvh graphische Sprachelemente
 Extreme Beschränkungen durch Fokus auf Datenbanken, daher nicht
(mehr) weit verbreitet.
7.1.3 Generation: 5. Deklarative Sprachen
 Beschreibung des Problems in einem (meist) mathematischen
Formalismus.
Lösung, basierend auf der Beschreibung, durch das System.
 Logische Sprachen, z.B. Prolog
 funktionale Sprachen, z.B. ML
 logisch-funktionale Sprachen
 (Zur Zeit) Keine wesentlichen Einsatzgebiete
7.1.4 Programmiersprachen heute
 Seit den Zeiten der Maschinensprachen hat eine Entwicklung zu mehr
Abstraktion stattgefunden
 Abstraktion des Algorithmus von einfachsten Maschinenbefehlen
(bestehend aus Zuweisungen, Vergleichen und Sprüngen) über
prozedurale Sprachen (mit ihren Mitteln der strukturierten Programmierung)
bis hin zu deklarativen Sprachen (die Probleme vollständig beschreiben,
deren Lösung dann generisch stattfinden kann)
 Abstraktion der Datenstrukturen von der „blanken“ Speicherstelle und
Register bis hin zu relationalen Strukturen (4GL-Sprachen) und
objektorientierten Strukturen (mit Vererbungsbeziehungen und
Datenkapselung)
 Stand heute:
 Tatsächlich sind die Sprachen der 3. Generation, insbesondere die mit
objektoerientierter Erweiterung, die zur Zeit wesentlichen.
Grund für das „Scheitern“ der 4GL-Sprachen ist der eingeschränkte Fokus
auf relationale Strukturen - Grund des „Scheiterns“ deklarativer Sprachen
ist die unangepasste Abstraktionsfähigkeit der Datenstrukturen und
insbesondere der Aufwand generischer Algorithmen.
7.2
Syntax und Semantik
 Im vorangegangenen Unterkapitel haben wir Programmiersprachen als
präzise, vollständig und eindeutig beschrieben. Diese Beschreibung trifft
tatsächlich aber nicht auf alle Aspekte der Sprache zu.
In diesem Unterkapitel sollen nun die Aspekte einer Programmiersprache beschrieben werden, sowie die Möglichkeiten, diese Aspekte
zu beschreiben.
 Inhalt
1. Syntax vs. Semantik
2. Syntax
3. Semantik
7.2.1 Syntax vs. Semantik
 Bei der Beschreibung einer Programmiersprache unterscheidet man
zwischen Syntax und Semantik der Sprache:
 Unter der Syntax einer Programmiersprache bezeichnet man den formalen
Aufbau, also die Struktur, einer Sprache
 Unter der Semantik einer Programmiersprache bezeichnet man, die
Bedeutung der Konstrukte einer Programmiersprache
 Beispiel:
 Syntax für die Zuweisung: linke_seite = rechte_seite;
 Semantik der Zuweisung: Der Wert der rechten Seite wird bestimmt
und wird an die Speicherstelle abgelegt, die
durch die linke Seite bezeichnet ist.
 Beachte
 Die Syntax kann (meist) vollständig formal angegeben werden
 Die Semantik wird meist nur informell beschrieben
 Fehler, die auf fehlerhaftes Verständnis der Semantik beruhen sind oft
schwer zu finden.
7.2.2 Syntax
 Wie wir gesehen haben, beschreibt die Syntax einer Programmiersprache deren Struktur.
Dabei ist lässt sich die Struktur von Programmiersprachen noch in zwei
Abstraktionsebenen einteilen:
 Lexikalische Struktur:
Hierunter versteht man die Struktur der „atomaren“ Elemente oder
Grundsymbole der Programmiersprache
 Syntaktische Struktur:
Hierunter versteht man die Zusammensetzung von Grundsymbolen der
Sprache zu komplexeren Strukturen
lexikalische Struktur
syntaktische Struktur
 Notation:
Die Syntax einer Sprache lässt sich (meist) formal beschreiben. Dazu
gibt es verschiedene Beschreibungsmittel bzw. Notationen.
7.2.2 Syntax: Lexikalische Struktur
 Die lexikalische Struktur: beschreibt also den Aufbau der Grundsymbole
aus einzelnen Zeichen
 Diese Zeichen sind Buchstaben, Ziffern und Sonderzeichen
 Die resultierenden Grundsymbole nennt man auch Token
 Beispiel:
 Zahlen bestehen aus beliebig vielen, aber mindestens einer Ziffer
 IEEE 754 Zahlen bestehen aus Ziffern und Kommas in Mantisse und
Exponent mit einem (kleinen oder großen) E dazwischen. Dabei sind einige
Teile optional
 Bezeichener beginnen mit einem Buchstaben, gefolgt von Ziffern,
Buchstaben und dem Sonderzeichen „_“
 Die lexikalische Struktur lässt sich mit
 regulären Ausdrücken beschreiben
 endlichen Automaten untersuchen
 Ein Programm zur Umsetzung lexikalischer Strukturen in Token nennt
man Scanner.
7.2.2 Syntax: Syntaktische Struktur
 Die syntaktische Struktur beschreibt also die Zusammensetzung von
Grundsymbolen der Sprache zu Ausdrücken, Anweisungen und letztlich
zu einem vollständigen Programm.
 Beispiel:
 Ein Ausdruck besteht aus:
 einem Ausdruck gefolgt von einem Operator, gefolgt von einem Ausdruck
z.B.: 5 * 7
 oder aber einer einzelnen Zahl
z.B. 5
 Eine abweisende Schleife besteht aus:
 dem Schlüsselwort „while“, einem boll‘schen Ausdruck (in Klammern) und einer
Anweisung.
z.B. while (a>5) i=i+1;
 Die syntaktische Struktur lässt sich durch Grammatiken beschreiben
 Ein Programm zur Analyse der syntaktischen Struktur (und zu dessen
weiteren Verarbeitung) nennt man Parser.
7.2.3 Semantik
 Die Semantik beschreibt also die Bedeutung der Konstrukte einer
Programmiersprache.
 Beispiel:
 if (a>5) then a=5 else a=0
Die Bedeutung dieser Alternative lässt sich wie folgt beschreiben:
Die bool‘sche Bedingung der Alternative wird ausgewertet:
Ist das Ergebnis „wahr“ so werden die Anweisungen des then-Zweiges
ausgeführt,
Ansonsten werden die Anweisungen des else-Zweiges ausgeführt.
 Die Beschreibungsformen - also die Notation der Beschreibung - sind
typischerweise nicht vorgeschrieben bzw. formalisiert.
 Da es für die meisten Programmiersprachen keine formalen Notationen
der Semantik gibt, gibt es auch meist kein Programm, welches für eine
Programmiersprache automatisch einen Übersetzer für Programme
dieser Sprache generiert.
 Scanner und Parser können automatisch generiert werden
 Compiler meist nicht
7.3
Reguläre Ausdrücke
 Im vorangegangenen Unterkapitel haben wir gesehen, dass die
lexikalische Analyse auf einer formalen Beschreibung der lexikalischen
Strukturen einer Programmiersprache aufbaut. Diese formale
Beschreibung ist die der „regulären Ausdrücke“.
Dieses Unterkapitel führt nun in die regulären Ausdrücke ein.
 Inhalt
1.
2.
3.
4.
5.
Beispiel
Definition: reguläre Ausdrücke
Definition: reguläre Sprachen
UNIX-Notation
Beispiele
7.3.1 Beispiel
 Beispiel Ziffer = [‘0‘-‘9‘]
Zahl = {Ziffer}+
Buchstabe = [‘A‘-‘Z‘‘a‘-‘z‘]
Bezeichner = {Buchstabe}({Ziffer}|{Buchstaben})*
 Notation (Auszug aus der UNIX-Notation)
 Einfache Notationsregeln:
 Hintereinander schreiben
bedeutet: Konkatenation
 |
bedeutet: Alternative
 Die Klammerung ist möglich (und äquivalent der math. Bedeutung)




[‘0‘-‘9‘] ist die Kurzform von ‘0‘ | ‘1‘ | ... | ‘9‘
{x} wird ersetzt durch die Definition von x
+ bedeutet: beliebig oft, aber mindestens einmal
* bedeutet: beliebig oft, auch kein mal
7.3.2 Definition: reguläre Ausdrücke
 Definition
 Reguläre Ausdrücke sind Formeln, mit denen (bestimmte) Sprachen
definiert werden könnn
 Sei  ein endlichen Alphabet bestehend aus Zeichen.
Reguläre Ausdrücke sind wie folgt induktiv definiert
1. e ist ein regulärer Ausdruck
2. Für jedes a  ist a ein regulärer Ausdruck

3. wenn a und b reguläre Ausdrücke sind, dann auch:
a) ab
a konkateniert mit b
b) (a|b)
a oder b
c) (a)*
a beliebig oft, einschließlich 0-mal
wobei die Wiederholung Vorrang vor der Konkatenation und diese wiederum
Vorrang vor der Alternative hat. Um Präzedenzen explizit darzustellen ist es
möglich, beliebig zu lammern.
 Beispiel: Sei ={a,b,c,d,e}: (ab|cd*)* ist ein regulärer Ausdruck denn,
a und b ist regulärer Audruck wg. 2., ab ist regulärer Ausdruck wg. 3.a
c und d ist regulärer Audruck wg. 2.,
d* ist regulärer Ausdruck wg. 3. c), cd* ist regulärer Ausdruck wg .3.a)
(ab|cd*) ist regulärer Ausdruck wg. 3.b)
(ab|cd*)* ist regulärer Ausdruck wg. 3.c)
7.3.3 Definition: reguläre Sprachen
 Definition
 Alle durch einen regulären Ausdruck r definierten Folgen von Zeichen
nennt man Wörter der Sprache L(r)
 Die Menge der durch reguläre Ausdrücke beschreibbaren Sprachen ist
genau der Menge der regulären Sprachen
 Beispiele:
  ={a,b}
 = {a,b,c}
r=e
r = a | bc | ccc
L(r) = { }
L(r) = {a,bc,ccc}
  = {a,b,c}
r = (abc|bc)a*(bc|ab)*
L(r) = {abcabc, bcabc, abcaab, bcaab, abcaabc, ....}
 Es gibt Sprachen, die sich nicht durch reguläre Ausdrücke definieren
lassen:
 L(r) = {ab,aabb,aaa,bbb, ....., anbn}
 Alle Programmiersprachen
7.3.3 UNIX-Notation - die klassischen Elemente
 Für Token einer real existierenden Programmiersprache ist die einfache
Notation regulärer Ausdrücke teilweise sehr umständlich.
 Beispiel:
Bezeichner: (a|b|c|....|z|A|B|...|Z|_)(a|b|c|....|z|A|B|...|Z|_|0|1|....|9)*
 Daher hat sich in der Informatik eine zwar komplexere aber dafür
flexiblere Notation eingebürgert:
Die UNIX-Notation
Die UNIX Notation übernimmt die folgenden Konstruktionsregeln (mit
den zugehörigen Präzedenzregeln) aus der „klassischen“ Notation für
reguläre Ausdrücke
1.
2.
3.
4.
5.
Konkatenation zweier reg. Ausdrücke erfolgt ohne expliziten Operator
Alternativen werden mittels j gebildet
ein normales\ Zeichen steht fur sich selbst
ein nachgestellter * steht für beliebige Wiederholung
Klammerung erfolgt durch ( und )
7.3.3 UNIX-Notation - Die Sonderzeichen
 Zusätzlich unterscheidet man in der UNIX Notation zwischen weiteren
Sonderzeichen und normale Zeichen.
 Weitere Sonderzeichen sind z.B. : * + [ ] ? ^ ( ) . $
 Falls ein Sonderzeichen nicht als solches interpretiert werden soll, ist ein
"\“ voranzustellen
 Die Bedeutung der Sonderzeichen ist wie folgt
6. . steht für ein beliebiges Zeichen außer '\n‚ (Zeilenumbruch)
7. Auch in Apostrophe eingeschlossene Strings werden verbatim interpretiert.
8. ein nachgestelltes + steht für nichtleere Wiederholung
9. ein nachgestelltes ? bezeichnet einen optionalen Anteil
10. ^ am Anfang eines regulären Ausdrucks steht für Zeilenanfang
11. $ am Ende eines regulären Ausdrucks steht für Zeilenende
7.3.3 UNIX-Notation - Die Zeichenklasse
 eine Zeichenklasse steht für genau ein Zeichen.
Sie kann durch Zeichen-Aufzählung x1, x2,... xn und Bereichsangaben
x1-xn gebildet werden:
 [x1-xn] steht für ein Zeichen aus dem Bereich und entsprich der klassischen
Notation x1|x2|... |xn
Beispiel: [0-9]
 [x1x2...xn] steht für genau ein Element aus der Menge der angegebenen
Zeichen
Beispiel: [abc_]
 Beide Schreibweisen (Bereich und Aufzählung) können beliebig kombiniert
werden.
Beispiel: [a-zA-Z0-9_]
 Ein ^-Zeichen am Anfang der Zeichnklasse ( [^....] ) spezifiziert die
komplementäre Zeichenmenge.
Beispiel: [^0-9] steht für ein beliebiges Zeichen außer einer Ziffer
7.3.4 Beispiele
1. Alle mit kleinem „a“ beginnenden Zeichenketten: a.*
2. Alle nichtleeren Dezimalziffernfolgen: [0-9]+
3. Alle Wörter, die aus genau 3 Zeichen bestehen und nicht mit einer Ziffer
enden: ..[^0-9]
4. Pascal-Bezeichner = [A-Za-z][A-Za-z0-9]*
5. C-Float-Literale = -?[0-9]+((\.[0-9]+)|((\.[0-9]+)?[eE]-?[0-9]+)
C-Float-Literale bestehen aus




einem Vorkomma-Anteil\ (ggf. mit Minuszeichen) (Syntax: -?[0-9]+)
einem optionalen Nachkomma-Anteil (Syntax: \.[0-9]+)
und einem ebenfalls optionalen Exponenten-Anteil (Syntax: [eE]-?[0-9]+).
Dabei ist zu beachten, dass entweder der Nachkomma-Anteil oder der
Exponent vorhanden sein muss. Wenn beides fehlt, liegt eine IntegerKonstante vor. Daher ist die folgende Spezifkation nicht korrekt:
-?[0-9]+(\.[0-9]+)?([eE]-?[0-9]+)?
 Viel komplizierter wird es in der Praxis nur selten !
7.4
Endliche Automaten
 Wie wir gesehen haben, lassen sich die Grundelemente einer
Programmiersprache, die Token, durch reguläre Ausdrücke formal
beschreiben. Es gibt nun eine zweite äquivalente Beschreibungsart, die
zudem der Ausgangspunkt für eine maschinelle Überprüfung von
Wörtern bezüglich gegebener regulärer Ausdrücke ist:
Endliche Automaten.
Diese sind Gegenstand dieses Unterkapitels
 Inhalt





Definition
Graphische Darstellung
Funktionsweise
Beispiel: NEA, DEA
Automaten und reguläre Ausdrücke
7.4.1 Definition
 Definitionen
 Ein endlicher Automat M ist ein 5-Tupel
M = (Z, , d, z0, E) mit:
 Z ist eine endliche Menge der Zustände
  ist das Eingabealphabet
mit Z   =
 d : Z x   Z ist die Überführungsfunktion
 z0 ist der Startzustand
 E  Z ist die Menge der Endzustände
 Ist in d die Wertemenge Z eindeutig für alle Zustände und Zeichen und ist
e  Z (e ist das “leere” Zeichen), so nennt man den Automaten
deterministisch ansonsten Indeterministisch.
 Die von M akzeptierte Sprache L(M) ist definiert als:
L(M) = {x  * | z0 geht mit x in einen Zustand aus E über}
7.4.2 Graphische Darstellung
 Ein endlicher Automat kann als gerichteter Graph dargestellt werden:




Die Zustände werden als Knoten repräsentiert
Die Überführungsfunktion wird als Kanten dargestellt
Der Anfangszustand wird mit einem eingehenden Pfeil markiert
Die Endzustände werden mit einem zweiten Kreis umringt
a
z3
M=
{
b a
b
z0
z2
b
a
z1
Z = z0, z1, z2, z3,
S = a,b,
d = (z0,b,z3), (z0,a,z1), (z1,b,z0), (z1,a,z2), (z2,b,z1), (z2,a,z3),
z0,
E = z3,
}
7.4.3 Funktionsweise
 Der endliche Automat versucht, ein Eingabewort, also eine Sequenz
von Eingabezeichen, zu „akzeptieren“.
 Der Automat befindet sich anfänglich im Eingangszustand zo
 Jetzt werden das Wort, Buchstabe für Buchstabe im Automat verarbeitet.
Dabei ergibt ein aktueller Zustand und der gerade gelsenen Buchstabe
über die Überführungsfunktion einen Folgezustand, der dann der aktuelle
Zustand für den Folgebuchstaben wird.
 Das Wort ist akzeptiert, wenn sich der Automat nach der Verarbeitung des
letzten Buchstabens in einem Endzustand befindet
 Das Wort ist nicht akzeptiert, wenn
 sich der Automat nach der Verarbeitung des letzten Buchstabens nicht in einem
Endzustand befindet, oder
 die Übergangsfunktion bei der Abarbeitung keinen Wert für einen aktuellen
Zustand und das zugehörige aktuell gelesene Zeichen findet.
 Beispiel:
 Der Automat des vorangegangen Beispiels akzeptiert z.B. b,aaa,abaa, ...
 Er akzeptiert nicht: aa (kein Endzustand), aab ( b in Z2 nicht definiert)
7.4.3 Beispiel: NEA, DEA
 Beispiel eines nichtdeterministischen endlichen Automaten (NEA)
z2
z3
a
e
a
z0
b
a
a
z1
 Beispiel eines (äquivalenten) deterministischen endlichen Automaten
(DEA)
b
a
b
b
z0
z2
z1
z3
a
a
a
 Jeder indeterministische endliche Automat lässt sich in einen
deterministischen endlichen Automaten (automatisch) umformen, der
die gleiche Sprache akzeptiert (also L(NEA) = L(DEA) )
7.4.3 Automaten und reguläre Ausdrücke
 Satz:
Die Menge der regulären Sprachen ist identisch mit der Menge, der von
endlichen Automaten akzeptierten Sprachen.
 Beweisidee:
Für jeden endlichen Automaten gibt es einen regulären Ausdruck, der
die vom Automaten akzeptierte Sprache beschreibt.
Umgekehrt gibt es für jeden regulären Ausdruck einen endlichen
Automaten, der die durch den regulären Ausdruck beschriebenen
Sprache akzeptiert.
Beweis durch Konstruktion eines Automaten aus einem regulären
Ausdruck und umgekehrt ( Compilerbau, 4. Semester)
 Beispiel: (a|bc)*
e
a
z2
e
z0
b
z2
c
z2
z2
e
7.5
Grammatiken
 Die Grundsymbole einer Programmiersprache, die deren lexikalische
Struktur definieren, lassen sich mit Hilfe regulärer Ausdrücke
beschreiben und mit endlichen Automaten überprüfen. Reguläre
Sprachen bzw. endl. Automaten sind aber nicht mächtig genug,
komplexere Strukturen wie z.B. syntaktische Strukturen einer
Programmiersprache zu beschreiben.
Dieses Unterkapitel stellt nun eine Beschreibungsform vor, die auch
(bestimmte) komplexere Strukturen, wie sie typisch für
Programmiersprachen sind, zu beschreiben vermag: Grammatiken.
 Inhalt
1.
2.
3.
4.
Beispiel aus der deutschen Sprache
Definitionen
Notationen
Chomsky Hierarchie
7.5.1 Beispiel: Deutsche Sprache
 Beispiel:
 Ein Satz ist eine Folge von Subjekt Prädikat und möglicherweise Objekt,
abgeschlossen mit einem Punkt (".")
 Ein Subjekt ist ein Eigenname oder ein Artikel, gefolgt von einem
Substantiv
 Ein Prädikat ist ein Verb
 Ein Objekt ist ein Artikel, gefolgt von einem Substantiv
 Eigenname: Adam, Eva
 Verb: ißt, beißt
 Artikel: der, die
 Substantiv: Apfel, Schlange
 Grammatik:
 Nichtterminalsymbole und Terminalsymbole bilden die Elemente
 Regeln zu deren Verwendung
 Ein Startsymbol (Satz)
7.5.1 Beispiel: Notation
 Beispiel
 Ein Satz ist eine Folge von Subjekt Prädikat und möglicherweise Objekt,
abgeschlossen mit einem Punkt (".")
<Satz> := <Subjekt> <Prädikat> [<Objekt>] .
 Ein Subjekt ist ein Eigenname oder ein Artikel, gefolgt von einem
Substantiv
<Subjekt> :=(<Eigenname> | <Artikel>) <Substantiv>
 Ein Prädikat ist ein Verb
<Prädikat> := <Verb>
 Ein Objekt ist ein Artikel, gefolgt von einem Substantiv
<Objekt> := <Artikel><Substantiv>
 Eigenname: Adam, Eva
<Eigenname> := "Adam" | "Eva"
 ....
7.5.1 Beispiel: Ein „Wort“ der Sprache
 Beispiel








<Satz>
<Subjekt>
<Artikel>
<Attribut>
<Adjektiv>
<Substantiv>
<Prädikat>
<Objekt>
:=
:=
:=
:=
:=
:=
:=
:=
<Subjekt> <Prädikat> <Objekt>
<Artikel> <Attribut> <Substantiv>
e | der | die | das
e | <Adjektiv> | <Adjektiv> <Attribut>
kleine | bissige | große
Hund | Katze
jagt | sieht
<Artikel> <Attribut> <Substantiv>
 Ableitungsbaum:
<Satz>
<Subjekt>
<Artikel>
<Attribut>
<Prädikat>
<Substantiv>
<Artikel>
<Adjektiv> <Attribut>
<Objekt>
<Attribut>
<Substantiv>
<Adjektiv>
<Adjektiv>
der kleine bissige Hund jagt
die
große
Katze
7.5.2 Definitionen
 Eine Grammatik G ist ein 4-Tupel G = (N, T, P, S) mit:
 N ist eine endliche Menge, die Menge der Nichtterminalen
 T ist eine endliche Menge, das Terminalalphabet
mit NT=
 P ist eine endliche Menge von Regeln oder Projektionen mit
P ist eine Teilmenge von (NT)+  (N T)*
die Grammatik heißt kontextfrei, wenn gilt:
P ist eine Teilmenge von N  (N T)*
 S  N ist das Startsymbol
 ein Wort v ist direkt ableitbar aus u (notiert: u 1 v) , wenn gilt:
u = xyz, v = xy’z (x,y Worte); y := y’ ist Regel in P
 ein Wort w ist ableitbar aus u (notiert: u  w), wenn gilt:
1
1
1
1
u  u1  u2  …  w (u1,u2,… Worte)
 Die von G dargestellte Sprache L(G) ist definiert als:
L(G) = {w  T* | S  w }
(S : Startsymbol)
7.5.2 Definition: Beispiel
 Eine Grammatik G ist ein 4-Tupel G = (<N>, T, P, S) mit:
 N ist eine endliche Menge, die Menge der Nichtterminalen
 T ist eine endliche Menge, das Terminalalphabet
mit NT=
 P ist eine endliche Menge von Regeln oder Projektionen mit
P ist eine Teilmenge von (NT)+  (N T)*
die Grammatik heißt kontextfrei, wenn gilt:
P ist eine Teilmenge von N  (N T)*
 S  N ist das Startsymbol
 Aus unserem Beispiel








<Satz>
<Subjekt>
<Artikel>
<Attribut>
<Adjektiv>
<Substantiv>
<Prädikat>
<Objekt>
:=
:=
:=
:=
:=
:=
:=
:=
<Subjekt> <Prädikat> <Objekt>
<Artikel> <Attribut> <Substantiv>
e | der | die | das
e | <Adjektiv> | <Adjektiv> <Attribut>
kleine | bissige | große
Hund | Katze
jagt | sieht
<Artikel> <Attribut> <Substantiv>
7.5.2 Definition: Beispiel
G=(
N= { <Satz>, <Subjekt>, <Prädikat>, <Objekt>, <Artikel>, <Attribut>,
<Substantiv>, <Adjektiv>}
T= { kleine, bissige, große, Hund, Katze, jagt, sieht}
P= {
<Satz>
:=
<Subjekt>
:=
<Artikel>
:=
<Attribut>
:=
<Adjektiv> :=
<Substantiv> :=
<Prädikat> :=
<Objekt>
:=
}
S = <Satz>
)
<Subjekt> <Prädikat> <Objekt>
<Artikel> <Attribut> <Substantiv>
e | der | die | das
e | <Adjektiv> | <Adjektiv> <Attribut>
kleine | bissige | große
Hund | Katze
jagt | sieht
<Artikel> <Attribut> <Substantiv>
7.5.2 Definition: Beispiele
 G = { N,T,P,A }, N = { A,B,C }, T = { a,b,c },
P = { A:=aAa, A:=BC, B:=bbB, B:=BC, B:=e, C:=Cc, C:=c }
 a2b2c3 a2  L(G)
 a4 b2 c b2 c a4  L(G)
 G = { N,T,P,S }, N = { A,B,C,S }, T = { a,b,c },
P = { S:=ABC, A:=ABA, C:=CBC, A:=a, B:=b, C:=c }
 {wT* | w= (ab)nac(bc)n, n>=1} = L(G)
 b2a2c3  L(G)
 G = { N,T,P,S }, N = { A,B,C,S }, T = { a,b,c },
P = { S:=ABC, A:=Aa, A:=a, B:=bBc, B:=b, C:=c }
 {wT* | w= anbncn, n>1}  L(G)
 a3b2c2  L(G)
 a2b2c3  L(G)
 …
7.5.3 Notationen: BNF / EBNF
 Die BNF (John Backus, Peter Naur, 1960) ist die Grundform und
entspricht der Definition
 eventuell erweitert um den alternativ-Operator (“|”)  siehe Beispiele
 Die EBNF erweitert die BNF um 3 (2) Operatoren
 den Alternativ Operator: |
 den Wiederholungs-Operator: { … }
Notiert auf der rechten Seite einer Regel, drückt er aus, dass der
geklammerter Ausdruck beliebig oft wiederholt werden kann - einschließlich
kein mal.
Teilweise wird die minimal und maximal mögliche Anzahl von
max
Wiederholungen zusätzlich notiert: { … } min
 der Optional-Operator: [ … ]
Notiert auf der rechten Seite einer Regel, drückt er aus, dass der
geklammerter Ausdruck ein oder keinmal wiederholt werden kann, also
optional ist.
 Es lässt sich zeigen, dass beide Notationen gleich mächtig sind, dass
sich also BNF notierte Grammatiken auch in EBNF notieren lassen
(trivial) und umgekehrt (wie ?)
7.5.3 Notationen: Syntaxdiagramme
 Syntaxdiagramme sind eine einfache graphische Repräsentation der
syntaktischen Struktur:
 Konkatenationen werden durch Sequenzen, Alternativen durch
Verzweigungen, Wiederholungen durch Rückkopplung dargestellt.
 Elemente sind Terminale und Nichtterminale
 Unser Beispiel (vereinfacht) im Syntaxdiagramm





<Satz> = <Subjekt> <Prädikat> [<Objekt>] .
<Subjekt> = <Eigenname> | <Artikel> <Substantiv>
<Prädikat> = <Verb>
<Objekt> = <Artikel><Substantiv>
<Eigenname> = "Adam" | "Eva"
Satz:
Eigename
Artikel Substantiv
Eigenname:
Adam
Eva
Verb
Artikel
Substantiv
.
7.5.4 Chomsky Hierarchie
 Grammatiken - und damit die von ihnen definierten Sprachen - bilden eine
Hierachie von “Mächtigkeiten”




Typ 0
Typ 1
Typ 2
Typ 3
rekursiv aufzählbar Keine Einschränkung
kontextsensitiv Linke Seite aller Regeln kürzer/gleich als rechte
kontextfrei
zusätzlich: linke Seite aller Regeln ein Nichtterminal
regulär
zusätzlich: rechte Seite beginnt mit Terminal
 Eine Sprache L heißt vom Typ x (x=0,1,2,3), falls es eine Typ x Grammatik
G gibt mit L(G) = L
 Reguläre Ausdrücke beschreiben Typ 3-Sprachen, kontextfreie
Grammatiken beschreiben Typ 1-Sprachen
Typ 0-Sprachen
Typ 1-Sprachen
Typ 2-Sprachen
Typ 3-Sprachen
nicht entscheidbar
entscheidbar, aber zu komplex
entscheidbar mit endl. Automat mit Stack
entscheidbar mit endl. Automat
7.5.4 Chomsky Hierarchie: Beispiel
 Aus den Teilmengenbeziehungen der Chomsky-Hierarchie lässt sich
also insbesondere ableiten
 dass alle Sprachen, die sich mit regulären Ausdrücken beschreiben lassen
auch durch kontextfreie Grammatiken darstellen lassen
 dass sich nicht notwendigerweise alle durch Grammatiken darstellbaren
Sprachen auch durch reguläre Ausdrücke beschreiben lassen
Endlicher
Automat
a
z3
z2
b a
b
z0
Grammatik
b
a
z1
<start> := <ab>b|a<ba>a<ba>a
<ab> := e | ab | ab<ab>
<ba> := e | ba | ba<ba>
7.6
Zusammenfassung des Kapitels
 Programmiersprache
 Was ist eine Programmiersprache / ein Programm
 Generationen von Programmiersprachen / Programmiersprachen heute
 Syntax und Semantik
 Syntax vs. Semantik
 Syntax / Semantik
 Reguläre Ausdrücke
 Definitionen: reguläre Ausdrücke und reguläre Sprachen
 UNIX-Notation
 Endliche Automaten
 Definition, Graphische Darstellung und Funktionsweise
 Automaten und reguläre Ausdrücke

Beispiel aus der deutschen Sprache
1. Definition und Notationen
2. Chomsky Hierarchie
Übungen
Übung 2.1
Information
1. Wieviele Fragen benötigen Sie beim „Zahlenraten“
a) um eine aus 100 Zahlen zu erraten
b) um eine aus n Zahlen zu erraten
2. Eine Nachrichtenquelle sendet Zeichen aus dem Alphabet
X = {a,b,c,d} mit den Wahrscheinlichkeiten p(a)=1/4, p(b)=p(c)=1/8
a)
b)
c)
d)
Berechnen Sie die Entropie der Quelle
Wie groß ist der Informationsgehalt der Nachricht „abcd“
Wie groß ist der mittlere Informationsgehalt der Nachricht „abcd“
Wie groß ist der mittlere Informationsgehalt einer Nachricht mit 1000
Zeichen
e) Wie groß ist der Informationsgehalt einer Nachricht mit 1000 Zeichen unter
der Annahme, dass alle Zeichen gleich wahrscheinlich sind.
Übung 2.2
Huffmann
1. Berechnen Sie
a) Informationsgehalt
jedes Symbols
b) Mittlerer Informationsgehalt des Alphabets
c) Huffmann Codierung
d) Redundanz Ihres
Huffmann-Codes
e) relative Redundanz
Ihres Huffman-Codes
des Alphabets der
deutschen Sprache
(siehe Tabelle)
Tip: Verwenden Sie eine
Tabellenkalkulation
Buch
stabe
Häufigkeit
Häufigkei
t in%
Buch
stabe
Häufigkeit
in %
Buchs
tabe
a
6,51
j
0,27
s
7,27
b
1,89
k
1,21
t
6,15
c
3,06
l
3,44
u
4,35
d
5,08
m
2,53
v
0,67
e
17,40
n
9,78
w
1,89
f
1,66
o
2,51
x
0,03
g
3,01
p
0,79
y
0,04
h
4,76
q
0,02
z
1,13
i
7,55
r
7,00
in %
Übung 2.3
Hamming
1. Bestimmen Sie
a) Die Hamming-Distanz des ASCII-Codes
b) Welche Bitfehler sind erkennbar ?
c) Welche Bitfehler sind korrigierbar ?
2. Bestimmen Sie die Hamming-Distanz der nach der Hamming-Methode
kodierten Codewörter.
a) Betrachten Sie dabei zunächst nur die Codewörter für 0000 bis 1111
b) Welche Bitfehler sind erkennbar ?
c) Welche Bitfehler sind korrigierbar ?
3. Betrachten Sie den mit der Hamming-Methode codierten Code für
„1000“
a) Kippen sie jedes Bit je einmal und bestimmen sie das gekippte Bit mit der
Hamming-Methode.
b) Was passiert, wenn zwei Bits gekippt sind - verdeutlichen Sie dies anhand
eines Beispiels.
Übung 3.1
Zahlensysteme
1. Die Duodezimalindianer haben zwölf Finger
a) Berechnen Sie nach dem Zahlensystem der Duodezimalindianer die
wichtigsten Werte des täglichen Lebens:
a) 300g Pizza
b) Eine Flasche Bier (0,5 bzw. 0,33 Liter)
c) ALDI 2.95 €
b) Konvertieren Sie die obigen Werte auch in Bin, Hex und Okt
2. Grundrechenarten (verwenden Sie keinen Rechner)
a)
b)
c)
d)
Berechnen Sie 568110 / 1910
Konvertieren Sie 568110 und 1910 ins Binärsystem
Dividieren Sie die Binärdarstellungen der beiden Zahlen
Machen Sie die Gegenprobe im Binärsystem
3. Konvertieren Sie 0,110 ins Binärsystem mit der Restwertmethode
4. Addieren Sie paarweise alle Zahlen von -3 bis +4 (26 Additionen),
verwenden Sie dabei die Darstellung negativer Zahlen im
Zweierkomplement.
Übung 3.2
Gebrochene Zahlen
1. (optional) Programmieren Sie in PHP4/HTML-Forms einen Konverter
zur Konvertierung ganzer und gebrochener Zahlen zwischen beliebigen
Zahlensystem und zur Darstellung im IEEE 754 float und double
Format.
2. Stellen Sie 
1. als IEEE 754 float-Zahl dar
2. (optional) als IEEE 754 double-Zahl dar
3. Geben Sie im Binärsystem und Dezimalsystem
1. den größt- bzw. kleinst-möglichen positiven bzw. negativen Wert einer
float-Zahl an (für IEEE 754 float)
Übung 3.3
IEEE 754
1. (optional)
Betrachten sie das Programm konvd auf der GDI-Website
(www.prof-kneisel.de -> Lehre -> GDI (Tabelle: Sonstiges))
1. Bestimmen Sie (durch Ausprobieren)
1.
2.
3.
4.
Vorzeichenbit,
Exponentenbits,
Mantissenbits
Bias
Für die Datentypen
a.
b.
c.
d.
Extended
Double
Currency
Single
Bemerkung:
Die im Programm konvd dargestellten Werte entsprechen den
Binärrepräsentationen von Borlands Delphi-Datentypen.
Übung 4.1
Strukturierte Datentypen
1. Formen Sie die „Kneisel“-Notation und die Beispiele aus Kapitel 4.3 in
C++ - Notation um.
2. Beschreiben Sie Gemeinsamkeiten und Unterschiede von
„Datenstruktur“, „Datentyp“ und „Variable“.
3. Was sind die Vor- und Nachteile von Arrays gegenüber verketteten
Listen
4. Definieren Sie einen Datentyp für das Objekt „Schachspiel“.
Berücksichtigen Sie dabei z.B. die Namen der Spieler, alle Züge, den
Gewinner, ...
5. Betrachten Sie den Stundenplan auf meiner Homepage
1. Skizzieren Sie einen Datentyp für das Objekt „Stundenpläne“
2. Welchen Speicherplatz benötigt eine Variable dieses Typs ?
3. An welchen Stellen sehen Sie Alternativen zu Ihrer Typdefinition ?
Übung 4.2
Abstrakte Datentypem
1. Definieren Sie den Datentyp für eine
a. einfach verkettete Liste (die Datenwerte seien vom Typ: integer)
b. doppelt verkette Liste (die Datenwerte seien vom Typ: integer)
<int>
<int>
<int>
...
<int>
<int>
<int>
...
2. Definieren Sie den Datentyp für ein beliebiges Netz - siehe Bild


der Datenwert jedes Knotens sei vom Typ integer
die maximale Anzahl von Nachfolgeknoten sei begrenzt)
<int>
<int>
<int>
<int>
<int>
<int>
<int>
<int>
<int>
Übung 5.1
Schleifen
1. Konstruieren Sie (beliebig) und wandeln Sie um ...
1. eine „While“-Schleife in eine „Do-While“-Schliefe
2. eine „Do-While“-Schleife in eine „While“-Schleife
3. Formulieren Sie Ihr Vorgehen für allgemeine „While“- und „Do-While“Schleifen, mit Bedingungen B und Aktionen.A.
2. Betrachten Sie Ihre konstruierte „While“-Schleife
1. Wandeln Sie diese in einen Algorithmus mit Sprung-Befehlen um.
2. Formulieren Sie Ihr Vorgehen für allgemeine „While“-Schleifen, mit
Bedingungen B und Aktionen.A.
3. Betrachten Sie Ihre konstruierte „Do-While“-Schleife.
1. Wandeln Sie diese in einen Algorithmus mit Sprung-Befehlen um.
2. Formulieren Sie Ihr Vorgehen für allgemeine „Do-While“-Schleifen, mit
Bedingungen B und Aktionen.A.
Übung 5.2
Spiel des Lebens
Das Spiel des Lebens findet in einer Welt statt, die einfachen Regeln
gehorcht. Die Welt besteht aus einem unendlich großen Schachbrett in
dessen Feldern primitive Tierchen, die “Nöpel” wohnen. Diese sitzen ein
Jahr unbeweglich auf ihren Feldern, unterhalten sich mit ihren Nachbarn es gibt erhitzte Diskussionen, Gedichtvorträge, Tratsch und Klatsch über
andere Nöpel, politische Reden, Deklamationen, Verleumdungen und
Schmeicheleien. Jedes Jahr genau um 12 Uhr in der Silvesternacht lösen
sich Nöbel entweder in Luft auf, bleiben sitzen oder werden aus dem Nichts
erschaffen. Dabei schlägt das Schicksal nicht blind zu:
 Hat ein Nöpel (von acht möglichen) keinen oder nur einen Nachbarn,
so stirbt er an Vereinsamung.
 Hat ein Nöpel vier oder mehr Nachbarn, so stirbt er an Erschöpfung ob
der vielen Plaudereien.
 Überleben tun Nöbel mit zwei und drei Nachbarn.
 Nöpel werden auf leeren Feldern geboren, wenn dort im Jahr zuvor
genau drei Nöpel gelebt haben
Übung 5.2
Die Generationen
 0,1,4,5,6,7,8
 2,3
3
Übung 5.2
 Der Gleiter
 Der Blinker
Interessante Völker
Übung 5.2
Spiel des Lebens
1. Überlegen Sie sich Rahmenbedingungen für das Spiel des Lebens
(Anhang B)
2. Formalisieren Sie dieses Problem
3. Stellen sie einen umgangssprachlichen Lösungsansatz auf
4. Formalisieren Sie den Lösungsansatz als Algorithmus
5. Spielen Sie den Algorithmus anhand eines Beispieles durch
6. Bewerten Sie den Algorithmus bezüglich seine Laufzeit und seines
Platzbedarfes
7. optional: Programmieren Sie dieses Spiel
Übung 5.3
Rekursion
1. Programmieren Sie die Fakultätsfunktion
1. Rekursiv
2. Iterativ
3. Ermitteln Sie die Laufzeiten beider Varianten in Abhängigkeit von n und
stellen Sie diese tabellarisch dar.
2. Optional:
1. Programmieren Sie für das „Weg des Springers“-Problem ein Programm
mit Backtracking.
2. Entwickeln Sie unterschiedliche Heuristiken zur Realisierung des
„waehleKandidat“-Blockes.
3. Zeigen Sie, durch Berechnung der ersten n Lösungen, welche Heuristik
die erfolgreichste ist.
Übung 5.4
Acht Damen Problem
 Das acht Damen Problem:
 Acht Damen sind so auf einem Schachbrett aufzustellen, dass keine
Dame eine andere bedroht:
 Eine mögliche Lösung:
 Formulieren Sie einen rekursiven Algorithmus zur Lösung des AchtDamen Problems.
 Programmieren Sie den Algorithmus
Übung 6.1
Turing-Maschine
1. Machen Sie sich mit der Funktionsweise des „Busy Beaver“-Programms
vertraut
 Vollziehen sie die 11 Schritte der ersten Turing-Tabelle.
2. Versuchen Sie sich selbst am Turing Simulator der IGS (Link auf meiner
Homepage)
3. Entwerfen Sie eine Turing-Maschine zur Multiplikation zweier natürlicher
Zahlen.
Übung 6.2
Einfache Verifikation
 Gegeben ist folgender Algorithmus
{a<0, b>0, c>0} // Vorbedingung P(a,b,c)
a=b;
d=b-a;
if (c == 0) then
d=5;
else
d=d+1;
1. Geben Sie eine Nachbedingung Q(d) für die Variable d an
2. Beweisen Sie dass sich durch den Algorithmus aus P(a,b,c) diese
Nachbedingung Q(d) ableiten lässt
3. Schreiben Sie einen zweiten Algorithmus, der ebenfalls die
Nachbedingung Q(d) aus P(a,b,c) ableiten kann
4. Verifizieren Sie Ihren Algorithmus
Übung 6.3
Denksportaufgabe
1. Gegeben sei folgendes Verfahren
In einem Topf seien s schwarze und w weiße Kugeln - insgesamt
mindestens eine. Solange mindestens zwei Kugeln im Topf sind, nimm
zwei beliebige Kugeln heraus. Falls Sie gleiche Farbe haben, wirf beide
weg und lege eine neue schwarze Kugel in den Topf. Falls sie
verschiedene Farben haben, wirf die schwarze weg und lege die weiße
zurück in den Topf.



1. Welche Farbe hat die letzte Kugel
2. Welche Aussage - die einen Hinweis auf die Antwort gibt - gilt vor, in und
nach der Schleife (Invariante)
3. Terminiert die Schleife ? Begründen Sie ihre Antwort.
Übung 6.4
Invariante
1. Betrachten Sie nochmals das Verfahren aus der vorgegangenen
Übung:
In einem Topf seien s schwarze und w weiße Kugeln - insgesamt
mindestens eine. Solange mindestens zwei Kugeln im Topf sind, nimm
zwei beliebige Kugeln heraus. Falls Sie gleiche Farbe haben, wirf beide
weg und lege eine neue schwarze Kugel in den Topf. Falls sie
verschiedene Farben haben, wirf die schwarze weg und lege die weiße
zurück in den Topf.
1. Beschreiben Sie das Verfahren als Algorithmus
1. Das „Nehmen“ dürfen Sie als Block voraussetzen.
1. Entwerfen Sie den Kopf dieses Blocks,
2. Beschreiben Sie seine Parameter
3. beschreiben Sie sein Verhalten in Form einer Vor- und Nachbedingung
2. Bestimmen Sie die Invariante
3. Beweisen Sie die Korrektheit Ihrer Nachbedingung
Übung 6.5
Vollständige Verifikation
1. gegeben ist der folgende Algorithmus zum schnellen Potenzieren
(Legendre Algorithmus)
// Vorbedingung P(V): a>0  b0
x = a; y = b; z = 1;
while y > 0 {
if odd(y) then
z = z*x;
y = y div 2; // Ganzzahldivision
x = x*x;
}
1. Was ist die Nachbedingung dieses Algorithmus
2. Bestimmen die die Schleifeninvariante
3. Beweisen Sie die Korrektheit de Legendre Algorithmus
Übung 6.6
Schranken
1. Angenommen, Ihr Algorithmus habe einen Aufwand von
g(n) = 5n3 + n + 1000 für alle n
a) Geben sie eine obere Schranke O(g(n)) an.
b) Beweisen Sie, dass ihre Schranke tatsächlich eine obere Schranke ist.
c) Konstruieren Sie einen Graphen fü die beiden Funktionen g(n) O(g(n) so,
dass der Schnittpunkt deutlich wird.
d) Geben Sie eine untere Schranke an
2. Sie haben zusätzlich einen Algorithmus mit O(2n) Aufwand. Vergleichen
Sie diesen Algorithmus mit dem Algorithmus aus 1.
a) Welches ist der „schnellere“ Algorithmus ?
b) Begünden Sie Ihre Antwort quantitativ
Übung 6.7
O-Notation
1. gegeben seien folgende Werte:
1,3,4,8,9,15,17,25,28,29,31,36,41,45
a) Zeichnen Sie einen sortierten Baum minimaler Tiefe, der mit den gegeben
Werten belegt ist.
b) Schreiben Sie einen Algorithmus, der den Baum aufspannt
(als Wiederholungs-Übung von Zeigern)
c) Gegeben ist der Suchalgorithmus aus „Häufige O-Ausdrücke: O(log n)“.
 Geben Sie für jeden Wert an, wie oft der Block durchlaufen wird
2. Formulieren Sie einen iterativen Algorithmus mit O(n4)
 Geben Sie eine kurze rechnerische Begründung für Ihre Antwort
Übung 6.8
Aufwand
1. Gegeben ist folgender Algorithmus:
do (list:*liste) {
i:integer;
for i=1 to no_of_elements(list) {
remove_last_element(list);
do (list)
// call list with one element less
}
a) Geben Sie den Aufwand an.
b) Belegen Sie Ihre Antwort rechnerisch
2. Gegeben ist folgender Algorithmus
for i=1 to n {
j=1;
while (j<i) {
j = j+2;
}
}
a) Geben Sie den Aufwand an.
b) Belegen Sie Ihre Antwort rechnerisch
Übung 7.1
Syntax und Semantik
1. Geben Sie Beispiele für
a) lexikalische Strukturelemente
b) syntaktische Strukturelemente
der Programmiersprache C++ an
2. Formulieren Sie die Semantik
a) einer while-Schleife
b) eines Unterprogrammaufrufes
in C++
3. recherchieren Sie nach weiteren Programmiersprachen
Übung 7.2
Reguläre Ausdrücke
1. Geben Sie reguläre Ausdrücke für
a) Integerliterale
b) Die Schlüsselwort: while, function, if
in C++, jeweils in „klassischer“ und in UNIX-Notation an
2. Geben Sie einen regulären Ausdruck zu folgenden Sprachen an:
a) Alle Folgen von Großbuchstaben, die jeden Vokal genau einmal in
alphabetischer Reihenfolge enthält:
Bsp.: SDFKJHZZTADGFPMNBEHGQIQWGFMNOLKHYXUQSKJH
b) Alle Dualziffernfolgen, die „001“ nicht als Teilfolge enthalten
Gegenbsp.: 10011100101010000
3. Welche Sprachen sind durch die folgenden regulären Ausdrücke
definiert ?
a) (0?|1*)*
b) (0|1)*0(0|1)(0|1)
c) /\*((\*[^/])|[\*])*\*/
Übung 7.3
Grammatiken
1. gegeben ist folgende Grammatik G:
G = { N,T,P,S }, N = { A,B,C,S }, T = { a,b,c },
P = { S:=ABC, A:=ABA, C:=CBC, A:=a, B:=b, C:=c }
a)
b)
c)
d)
e)
Ist die Grammatik kontextfrei ? Begründen Sie Ihre Antwort
Beweisen Sie: abababcbc  L(G)
Begründen sie verbal, weshalb b2a2c3  L(G)
Geben Sie einen regulären Ausdruck R an mit L(R) = L(G)
Welchem Typ der Chomsky-Hierachie entspricht die Sprache, die durch G
definiert ist ?
f) Ist die Sprache L(G) vom Chomsky-Typ-0 ? Begründen Sie Ihre Antwort
Lösung 2.1
Information
1. Wieviele Fragen benötigen Sie beim „Zahlenraten“
a) 7
b) nächste_ganze_Zahl_größer( ld n)
2. Eine Nachrichtenquelle sendet Zeichen aus dem Alphabet
X = {a,b,c,d} mit den Wahrscheinlichkeiten p(a)=1/4, p(b)=p(c)=1/8
a)
b)
c)
d)
e)
H(x) = p(x) *h(x) = ((1/4*2)+(1/8*3)+(1/8*3)+(1/2*1)) bit = 1,75 bit
(2+3+3+1) bit = 9 bit
4 * 1,75 bit = 7 bit
1000 * 1,75 bit = 1750 bit
1000 * H(x) = 1000 * (4 * (1/4 * 2 bit)) = 2000 bit
Lösung 2.2
Huffmann
a) siehe Tabelle rechts: h(x)
b) mittlerer Informationsgehalt:
H(x) = 4,06 bit
Redundanz bei 8bit-Kodierung
(z.B. ASCII mit Parity-Bit):
R = L-H = 8 bit - 4,06 bit = 3,94 bit
r = R/L = 0,49
a
b
c
d
e
f
g
h
j
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
p(x)(in %)
6,51
1,89
3,06
5,08
17,40
1,66
3,01
4,76
7,55
0,27
1,21
3,44
2,53
9,78
2,51
0,79
0,02
7,00
7,27
6,15
4,35
0,67
1,89
0,03
0,04
1,13
h(x) (in Bit)
3,94
5,73
5,03
4,30
2,52
5,91
5,05
4,39
3,73
8,53
6,37
4,86
5,30
3,35
5,32
6,98
12,29
3,84
3,78
4,02
4,52
7,22
5,73
11,70
11,29
6,47
p(x) * h(x)
0,2566
0,1082
0,1539
0,2184
0,4390
0,0982
0,1521
0,2091
0,2814
0,0230
0,0771
0,1672
0,1342
0,3280
0,1334
0,0552
0,0025
0,2686
0,2749
0,2474
0,1967
0,0484
0,1082
0,0035
0,0045
0,0731
Lösung 2.2
q
Huffmann
c) Beispiele:
a 0101
b 000010
c 01000
d 1111
e 001
f 000001
...
x
qx (0,05) y
qxy (0,09) j
jqxy (0,36) v
jqvxy (1,03) p
z
jqpvxy (1,82) f
b
fjqpvxy (3,48)
o
w
m
ow (4,40) u
g
gm (5,54)
ouw (8,75) n
...
dghmt (21,53)
o
1
dghmntouw (40,06)
kz (2,34)
bkz (4,23)
bfjkqpvxyz (7,71)
c
i
l
cl (6,50)
a
r
1
s
...
o
bfijkqpvxyz (15,26) e
o
acl (13,01)
...
befijkqpvxyz (32,66)
o
rs (14,27)
...
...
aclrs (27,28)
1
abcefijklqprsvxyz (59,94)
Die Bezeichnung der Kanten mit 0 oder 1 ist willkürlich
d
dh (9,84)
...
nouw (18,53)
k
h
gmt (11,69)
...
...
t
o
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
p(x) (in %)
6,51
1,89
3,06
5,08
17,40
1,66
3,01
4,76
7,55
0,27
1,21
3,44
2,53
9,78
2,51
0,79
0,02
7,00
7,27
6,15
4,35
0,67
1,89
0,03
0,04
1,13
Lösung 2.2
Huffmann
d) H(x) = 4.,06 bit
L = 4,1 bit
R = L-H = 0,04 bit
e) r = R/L = 0,01
a
b
c
d
e
f
g
h
j
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
p(x) (in %)
6,51
1,89
3,06
5,08
17,40
1,66
3,01
4,76
7,55
0,27
1,21
3,44
2,53
9,78
2,51
0,79
0,02
7,00
7,27
6,15
4,35
0,67
1,89
0,03
0,04
1,13
l(x)
4
6
5
4
3
6
5
4
4
9
7
5
5
3
5
7
11
4
4
4
4
8
5
11
10
7
p(x)*l(x)
0,2604
0,1134
0,1530
0,2032
0,5220
0,0996
0,1505
0,1904
0,3020
0,0243
0,0847
0,1720
0,1265
0,2934
0,1255
0,0553
0,0022
0,2800
0,2908
0,2460
0,1740
0,0536
0,0945
0,0033
0,0040
0,0791
Lösung 2.3
Hamming
1. Hamming-Distanz bei ASCII-Code
a) D=1
b) (D-1) = 0
c) (D-1)/2 = 0
2. Hamming-Codierung für 0000 - 1111
a) D=3 (durch Vergleich der Distanz zwischen allen Codes)
b) 2-bit Fehler können erkannt werden
c) 1-bit Fehler können korrigiert werden
0000000
0000111
0011001
0011110
0101011
0101100
0110011
0110100
1001011
1001100
1010010
1010101
1100001
1100110
1111000
1111111
Lösung 2.3
Hamming
3. Betrachten Sie den mit der Hamming-Methode codierten Code für
„1000“
a) 1001011
1001010
1001001
1001111
1000011
1011011
1101011
0001011
P-Bits falsch
1
2
1,2
4
1,4
2,4
1,2,4
=> Fehler bei bit
1
2
3
4
5
6
7
b) Kippen von Bit 1 und Bit 6:
1101010
1,2,4
7
es wird ein Fehler erkannt (gut !).
Allerdings wird der Fehler bei Bit 7 erkannt, wobei der Code bei der
Korrektur also fälschlicherweise zu 0101010 korrigiert wird, statt zu
1001011
Lösung 3.1
Zahlensysteme
1. Die Duodezimalindianer haben zwölf Finger
a) Berechnen Sie nach dem Zahlensystem der Duodezimalindianer die
wichtigsten Werte des täglichen Lebens:
a) 21012g Pizza
b) Eine Flasche Bier (0,612 bzw. ca. 0,3B62A68781B05912 Liter)
c) ALDI ca. 2,B4972497249724 €
b) Bin: 100101100 0,1
Okt: 454
0,4
Hex: 12C
0,8
0,01010100011110101110000
0,25075341217270243
0,547AE147AE145
10,111100
2,74631
2,F333333
Lösung 3.1
Zahlensysteme
2. Grundrechenarten
568110 : 1910 = 299
38
188
171
171
171
000
100101011 * 10011
100101011
100101011
100101011
1011000110001
1011000110001 : 10011 = 100101011
10011
00011001
10011
0011010
10011
11100
10011
10011
10011
00000
Lösung 3.1
3. 0,110
2 ·
2 ·
2 ·
2 ·
2 ·
2 ·
2 ·
2 ·
...
0,1
0,2
0,4
0,8
0,6
0,2
0,4
0,8
=
=
=
=
=
=
=
=
0,2
0,4
0,8
1,6
1,2
0,4
0,8
1,6
Zahlensysteme
-->
-->
-->
-->
-->
-->
-->
-->
Ziffer:
Ziffer:
Ziffer:
Ziffer:
Ziffer:
Ziffer:
Ziffer:
Ziffer:
0
0
0
1
1
0
0
1
Also: 0,000110011001100...
4. 44 65 72 20 42 61 6C 6C 20 69 73 74 20 72 75 6E 64 2E
ASCII:
LongInt
......
Der Ball ist rund.
1147499040 1113681004 543781748 544372078 1680736256
(mit 0en aufgefüllt)
Lösung 3.1
Zahlensysteme
4. Subtraktion durch Addition des Zweierkomplementes
0
-1
-2
-3
0000
1111
1110
1101
4
0100
0100 (1)0011
(1)0010
(1)0001
3
0011
0011 (1)0010
(1)0001
(1)0000
2
0010
0010 (1)0001
(1)0000
1111
1
0001
0001 (1)0000
1111
1110
0
0000
0000
1111
1110
1101
-1 1111
1111 (1)1110
(1)1101
(1)1100
-2 1110
1110 (1)1101
(1)1100
(1)1011
-3 1101
1101 (1)1100
(1)1011
(1)1010
-4
-5
-6
1100
1011
1010
Lösung 3.2
Gebrochene Zahlen
3.  = 3,14159265358979311...10 =
11,00100100001111110110101010001000100001011010001100...2
Mantisse
Exponent
0,1100100100001111110110102 * 22
VEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM
01000000010010010000111111011010
4. Maximalwerte (bei bias = 126):
größte negative
kleinste negative
kleinste positive
größte positive
1
1
0
0
11.10
00..0
00..0
11.10
Number
sign
normalized number
0/1
denormalized number 0/1
111...11
000...01
000...01
111...11
exponent
01 to FE
00
 - 1 *
= - 2-23
=
2-23

1 *
2127
* 2-126 = - 2-149
* 2-126 = 2-149
2127
mantissa
any value
any value
Lösung 3.3
IEEE 754
Lösung 4.1
Strukturierte Datentypen
 1. Umformen der „Kneisel“-Notation - Einfache Datentypen





bool switch1;
switch1 = false;
// = 0
switch1 = switch1 && (!switch1); // = 1 and 0 = 0
int i;
i = 1;
// = 1
i = i + 32;´
// = 1 + 32 = 33
char symbol;
symbol = ´A´;
// = „A“
symbol = symbol + 32;´
// = „A“ + 32 = „a“
enum ampelfarbe {gruen,gelb,rot};
ampelfarbe = gruen;
// = gruen
ampelfarbe = ampelfarbe +1 ; ´ // = gruen + 1 = gelb
float pi, flaeche, radius;
// all real !
pi
= 3.141; // needs not to be more accurate
radius = 5;
// might be changed by user
flaeche = 2 * pi * pow(radius,2);
// common formula
Lösung 4.1
Strukturierte Datentypen
 1. Umformen der „Kneisel“-Notation - Strukturierte Datentypen
 float m[3][2];
float v[4];
v[2] = 5.03; v[3] = 4.12;
m[0][1] = v[2] * 12 - v[3];
 struct { int tag;
int monat; } d ;
d.monat = 10;
d.tag
= 20;
 struct { char[20] name;
enum {m,f} sex;
union { int IQ;
real muscle; }
} adam, eva;
 typedef struct Datum {int year;
enum month {jan,feb,...};
int day; } Akt_Datum; // Akt_Datum hier
struct { char[20] surname;
char[20] forename;
Datum
birthday; } Person;
// alternativ: Datum Akt_Datum;
Lösung 4.1
Strukturierte Datentypen
2. siehe Kapitel 4.1
3.
Arrays
maximale Anzahl der Elemente
ist bekannt
Elemente nur eines Typs
erlaubt
Belegung des Speicherbereichs für
maximale Anzahl von Elementen
Einfacher Zugriff über Index
Einfache Implementierung
Sortierung „nur“ durch Umkopieren
möglich
...
verkettete Listen
maximale Anzahl der Elemente
ist nicht bekannt
Elemente unterschiedlichen
Typs (einfacher) möglich
Belegung nur des tatsächlich
benötigten Speicherbereiches
Zugriff durch Durchlaufen der
Liste
„Komplexere“ Implementierung
Sortierung durch neue Verkettung
möglich
...
Lösung 4.1
Strukturierte Datentypen
4,5 Es gibt (unendlich) viele Lösungen für die Konstruktion einer
Datenstruktur, daher sei hier nur eine mögliche Vorgehensweise
beschrieben:
 Suche alle beteiligten Objekte (z.B. durch Brainstorming)
 Stelle die Objekte zueinander in Beziehung
 Ist-Teil-von-Beziehung (Aggregation)
 ... (bei OO-Sprachen insb.: Erbt von)
 Stelle die Wertebereiche fest
 Gibt es „generische“ Objekte ( = grundlegende Objekte, die z.B. in
mehrerern Aggregationen vorkommen, auch in anderen Objekten)
 Bilde „generische Objekte entsprechend Ihrer Aggregationen als Record
(oder bei Listenstruktur als Array) ab
 Bilde das zu modellierende Objekt - auch unter Verwendung der
generischen Objekte -als Record (bzw. Liste) ab.
 Beachte die Vor- und Nachteile dynamischer Strukturen. Eventuell
benötigt man aus Effizienzgründen (-> Algorithmik) weitere Hilfsobjekte.
Lösung 4.2
Abstrakte Datentypen
1. in C++ Notation
struct list {int
value;
next *list; };
<int>
<int>
<int>
...
struct list{ int value;
naxt *list;
prev *list; }
<int>
<int>
<int>
...
2. in C++ Notatioon
struct net (int
value;
next* net[max_succesors]; };
<int>
<int>
<int>
<int>
<int>
<int>
<int>
<int>
<int>
Lösung 5.1
Schleifen
1. while (x < 5)
{
x = x + 1; 
}
if (x < 5) then
do {
x = x + 1;
}
while (x < 5)
while B
{
A

}
if B then
do {
A
}
while B
do {
x = x + 1; 
}
while (x < 5)
x = x + 1;
while (x < 5) {
x = x + 1;
}
do {
A

}
while B
A
while B {
A
}
2. 1: if x >= 5 goto 2
x = x + 1;
goto 1
2: ...
1: if !B goto 2
A
goto 1
2: ...
3. 1: x = x + 1;
if x < 5 goto 1
2: ...
1: A
if B goto 1
2: ...
Lösung 5.2
1.
2.
Spiel des Lebens: Aufgabe
Überlegen Sie sich Rahmenbedingungen für das Spiel des Lebens
(Anhang B)
Formalisieren Sie dieses Problem
Gegeben ist:
Eine zweidimensionales „Spielfeld“
Annahme:
die Grenzen werden verbunden.
Auch möglich: „Unendliche“ Grenzen, „abschneidende“ Grenzen
Anfangszustand:
beliebige Nöpelpositionen im Spielfeld
Regeln:
entsprechend der Spielregeln für „Spiel des Lebens“
Gesucht:
„Zwischenzustand“ nach beliebigen Generation (entsprechend der Regeln)
Optional: Erkennung von „Endzuständen“
Lösung 5.2
Spiel des Lebens: Ansätze
3. Stellen sie einen umgangssprachlichen Lösungsansatz auf
Entwurf der Datenstrukturen - zwei Ansätze:
Der Spielfeldzustand wird als zweidimensionales Feld repräsentiert
Der Spielfeldzustand wird über die Positionen der Nöpel präsentiert
Entwurf des Algorithmus
act_state = Startzustand
solange kein Endzustand {
get_next_state (act_state, next_state);
}
zwei entsprechende Ansätze:
get_next_state (In: act_state, Out: next_state)
Der Spielfeldzustand wird als zweidimensionales Feld repräsentiert:
{ durchlaufe Felder und setze Nöpel „entsprechend“ }
Der Spielfeldzustand wird über die Positionen der Nöpel präsentiert:
{ durchlaufe Nöpelliste und setze Nöpel „entsprechend“ }
Vor- / Nachteile ?
Lösung 5.2
Spiel des Lebens: Feld
 0,1,4,5,6,7,8
 2,3
3
3. a) Der Spielfeldzustand wird als zweidimensionales Feld repräsentiert
get_next_state (In: act_state, Out: next_state)
{
// determine survivors
durchlaufe act_state // zweifach-verschachtelte Schleife
{
falls act_state[act_field] hat 2,3 Nachbarn in act_state
setze next_state[act_field]
}
// determine babies
durchlaufe next_state // zweifach-verschachtelte Schleife
{
falls next_state[act_field] hat 3 Nachbarn in act_state
setze next_state[act_field]
}
}
Lösung 5.2
Spiel des Lebens: Liste
 0,1,4,5,6,7,8
 2,3
3
3. b) Der Spielfeldzustand wird über die Positionen der Nöpel präsentiert
get_next_state (In: act_state, Out: next_state)
{
durchlaufe act_state // einfache Schleife durch Nöpelliste
{
// determine survivors
find_neighbors(act_nöpel, no_of_neighbors)
falls no_of_neighbors = 2 oder 3
kopiere act_nöpel nach next_state
// determine babies
durchlaufe nachbar_nöpel von act_nöpel // max. 8
{
find_neighbors(nachbar_nöpel, no_of_neighbors)
falls no_of_neighbors = 3
kopiere nachbar_nöpel nach next_state
}
}
}
Lösung 5.2
Spiel des Lebens: Strukturen
3. Stellen sie einen umgangssprachlichen Lösungsansatz auf
Entwurf der Datenstrukturen - zwei Ansätze:
Der Spielfeldzustand wird als zweidimensionales Feld repräsentiert
act_state: array [1..max_reihen][1..max_spalten] of boolean;
0
0
1
0
0
0
0
0
1
1
1
0
0
0
0
...
0
1
0
0
0
0
...
Der Spielfeldzustand wird über die Positionen der Nöpel präsentiert
typedef struct nöpel {reihe: int;
spalte: int ; // next_nöpel: *nöpel
} ;
act_state: array [1..max_nöpel] of nöpel;
1
3
2
2
2
3
2
4
3
3
...
Lösung 5.2
Spiel des Lebens: Komplexität
6. Bewerten Sie den Algorithmus bezüglich seine Laufzeit und seines
Platzbedarfes
get_next_state (In: act_state, Out: next_state)
{
durchlaufe act_state // einfache Schleife durch Nöpelliste
{
// determine survivors
find_neighbors(act_nöpel, no_of_neighbors) // Durchsuche
// alle Nöpel
falls no_of_neighbors = 2 oder 3
kopiere act_nöpel nach next_state
// determine babies
durchlaufe nachbar_nöpel von act_nöpel // max. 8
{
find_neighbors(nachbar_nöpel, no_of_neighbors)
falls no_of_neighbors = 3
kopiere nachbar_nöpel nach next_state
}
} // Zeit: Nöpel * ( Nöpel + ( 8 * Nöpel ) ) = 9 * Nöpel 2
}
// Platz: 2 * Nöpel
Lösung 5.3
Rekursion
1. Programmieren Sie die Fakultätsfunktion
fakultaet (IN: n:integer, OUT: result:integer) {
if (n == 0) then result = 1;
else {
fakultaet (n-1, result);
result = result * n;
}
}
fakultaet (IN: n:integer, OUT: result:integer) {
result; old_result : int;
// declaration
result = 1; old_result = 1 // initialization
for i=1 to n {
result = i * old_result;
old_result = result
}
}
// Anzahl Multiplikationen in beiden Fällen proportional n
Lösung 5.4
Acht Damen Problem
1. siehe Homepage
Lösung 6.1.1 Turing-Maschine
 Vollziehen sie die 11 Schritte der ersten Turing-Tebelle.
1,_
1,1
2,_
2,1
3,_
3,1
4,_
4,1
2,1,>
3,1,<
3,1,>
H,1,>
1,1,<
2,_,<
H,_,>
H,_,>
1
2
3
4
5
6
7
8
9
10
11
State
2
3
1
3
2
3
1
3
1
2
H
Ausgangszustand,Zeichen  Folgezustand,schreibeZeichen,Aktion
Lösung 6.1.2 Turing-Maschine
 Eingabe der
initialen
Bandinschrift
 Eingabe der
Turing-Tabelle
Zustand x Zeichen

Folgezustand x
Zeichen x Aktion
Beispiel:
1,_  1,_,>
Lösung 6.1.3 Turing-Maschine
 Aufgabenstellung
 Entwerfen Sie eine Turing-Maschine zur Multiplikation zweier natürlicher
Zahlen.
 Spezifikation
 Eingabespezifikation





Die Zahlen werden durch die entsprechende Anzahl von ‚1‘ am Band dargestellt
Zwischen den Zahlen befindet sich ein ‚x‘ am Band
Hinter der letzten Zahl ist ein =- Zeichen am Band
Das restliche Band ist mit ‚0‘ beschrieben.
Der Schreib/Lesekopf befindet sich links von der 1. Zahl.
 Ausgabespezifikation
 Das Ergebnis ist hinter dem =, durch eine entsprechende Anzahl von ‚1‘
darzustellen.
 Beispiel:
 Die zwei Zahlen 3 und 4 sind mittels eines Turing-Programmes zu
multiplizieren
Lösung 6.1.3 Turing-Maschine
 Idee:
1. Kopiere alles vor
dem =
(den 2.Multiplikator)
ans Ende
2. Mache dies für jede
1 vor dem X
(den 1.Multiplikator)
 Siehe Anhang C
SucheStart
0
SucheStart
0
R
SucheStart
1
SucheZahl2
0
R
SucheStart
X
EndZustand
X
L
SucheZahl2
1
SucheZahl2
1
R
SucheZahl2
X
Zahl2Start
X
R
Zahl2Start
1
GeheEnde
0
R
Zahl2Start
=
Mach1Aus0
=
L
GeheEnde
1
GeheEnde
1
R
GeheEnde
=
SucheNull
=
R
SucheNull
1
SucheNull
1
R
SucheNull
0
HolNaechsten1
1
L
HolNaechsten1
1
HolNaechsten1
1
L
HolNaechsten1
=
HolNaechsten1
=
L
HolNaechsten1
0
Zahl2Start
0
R
Mach1Aus0
0
Mach1Aus0
1
L
Mach1Aus0
X
Zahl1Start
X
L
Zahl1Start
1
Zahl1Start
1
L
Zahl1Start
0
SucheStart
0
R
Lösung 6.2
Einfache Verifikation
 Gegeben ist folgender Algorithmus
{a<0, b>0, c>0}
a=b;
{a=b, b>0, c>0}
d=b-a;
{d=b-a, a=b, b>0, c>0}  {d=0, b>0, c>0}
if (c == 0) then
{d=0, b>0, c>0, c=0}
d=5;
{d=5, b>0, falsch}  {d=1}
// aus falsch lässt sich alles folgern
else
{d=0, b>0, c>0, c<>0}  {d+1=1, b>0, c>0}
d=d+1;
{d=1, b>0, c>0}
{d=1, b>0, c>0}  {d=1}
Lösung 6.3
Denksportaufgabe
1. Denksportaufgabe



1. Welche Farbe hat die letzte Kugel ?
Die Farbe der letzten Kugel ist abhängig von der Anzahl der weißen
Kugeln:
Ist die Anzahl gerade, so ist die letzte Kugel schwarz
Ist die Anzahl ungerade, so ist die letzte Kugel weiß
2. Welche Aussage gilt vor, in und nach der Schleife (Invariante)
Ist die Anzahl der weißen Kugeln gerade, so bleibt sie gerade
Ist die Anzahl der weißen Kugel ungerade, so bleibt sie ungerade
Es werden entweder 2 weiße Kugeln entfernt oder keine.
3. Terminiert die Schleife ? Begründen Sie ihre Antwort.
JA. Die Anzahl der Kugeln vermindert sich bei jedem Zug um genau eine
(nach Algorithmus: 2 nehmen, eine geben). Beim Erreichen von 2 Kugeln
wird die Schleife noch einmal durchlaufen und terminiert mit einer Kugel.
Lösung 6.4
{s+w >= 1}
Invariante



x=s; y=w;
{x=s, y=w, x+y  1}
{INV: ( (odd(w)odd(y))  (even(w)even(y)) )  x+y1 }
while (x+y>1)
{
{INV  x+y>1} // Vorbedingung für „take“: x+y>1
take(a,b)
// OUT: a no. black, b no white (drawn)
{a+b=2, a,b0} // = Nachbedingung für „take“
switch a: {
// a = no of black bullets drawn
case 0: {x=x+1; y=y-2}; {INV} // add black, remove two w.
case 1; (x=x-1);
{INV} // remove black
case 2; (x=x-1);
{INV} // remove black
}
{INV}
}
{INV   x+y>1 
( ((odd(w)odd(y))  (even(w)even(y)) )  x+y1  x+y1 
( ((odd(w)odd(y))  (even(w)even(y)) )  x+y=1) }
Lösung 6.5
Vollständige Verifikation
// Vorbedingung P(V): a>0  b0
x = a; y = b; z = 1; // x=a  y=b  z=1  x>0  b0
{ INV: zxy=ab  y0 }
while y > 0 {
{INV  y>0  (z*x/x)*xy=ab  y>0 }
if odd(y) then
z = z*x; { odd(y)  z/x*xy=ab  y>0  z*xy-1=ab  y>0 }
// else
{ even(y) 
z*xy =ab  y>0 } 
{ ( odd(y)  z*x(2(y div 2)+1)-1=ab  2(y div 2)+1>0 ) 
( even(y)  z*x2(y div 2)
=ab  2(y div 2) >0 )
}
y = y div 2; // Ganzzahldivision
{ ( odd(y)  z*x(2y+1)-1=ab  2y+1>0  z*x2y=ab  2y0 ) 
( even(y)  z*x2y
=ab  2y >0  z*x2y=ab  2y>0 )
}
x = x*x;
{ (odd(y)  z*xy=ab  2y0)  (even(y)  z*xy=ab  2y>0) 
z*xy=ab  ((odd(y)2y0)  (even(y)2y0))  z*xy=ab  y0 }
}
{ INV  (y0)  (z*xy=a*b)  (y=0)  z*x0=ab = Q(V) }
Lösung 6.6.1 Schranken
1. g(n) = 5n3 + n + 1000 für alle n
a) Behauptung: Die Laufzeit von g(n) ist O(n3), also f(n)=n3,
b) Beweis:
Es muss Konstanten c und n0 geben, so dass gilt
5n3 + n + 1000  c n2, für alle n > n0
setze z.B. n0=10 und c=6, dann gilt:
n3 > n + 1000 gilt für n11, n  
5n3 + n + 1000  5n3 + 100n  5n3+n3 = 6n3
c) 
14000
n3
12000
10000
8000
6000
4000
2000
d) z.B.: 5n3
0
1
2
3
4
5
6
7
8
9
10
11
12
13
Lösung 6.6.2 Schranken
2. Sie haben zusätzlich einen Algorithmus mit O(2n) Aufwand. Vergleichen
Sie diesen Algorithmus mit dem Algorithmus aus 1.
a) Welches ist der „schnellere“ Algorithmus ?
Für kleine n (n<14) ist der Algorithmus mit O(2n) der schnellere, ansonsten
der mit g(n) = 5n3 + n + 1000
b) Begründen Sie Ihre Antwort quantitativ
35000
2n
30000
25000
20000
15000
10000
5000
0
1
2
3
4
5
6
7
8
9
10
11 12
13
14 15
Lösung 6.7.1 O-Notation
1. gegeben seien folgende Werte: 1,3,4,8,9,15,17,25,28,29,31,36,41,45
17
Anzahl Aufrufe 1
8
3
1
31
9
4
2
28
15
25
41
29
36
3
45
4
node: array[1..14] of knoten;
// Normalerweise wird der Speicher dynamisch allokiert
node[1].value = 17;
node[12].value = 41;
node[1].left = &node[2];
node[12].left = &node[13];
node[1].right = &node[3];
node[12].right = &node[14];
node[2].value = 8;
node[13].value = 36;
node[2].left = &node[4];
node[13].left = nil;
node[2].right = &node[5];
node[13].right = nil;
node[3].value = 31;
node[14].value = 45;
node[3].left = &node[6];
node[14].left = nil;
node[3].right = &node[7];
node[14].right = nil;
...
Lösung 6.7.2 O-Notation
2. Formulieren Sie einen iterativen Algorithmus mit O(n4)
for (i=1 to n) {
for (j=1 to n) {
for (k=1 to n) {
for (l=1 to k) { // Statements
}
}
}
}
Aufwand: nn(n(n+1))/2 = n2(n2/2+n/2)=n4/2 + n3/2
 Laufzeit O(n4)
Lösung 6.8
Aufwand
1. do (list:*liste) {
i:integer;
for i=1 to no_of_elements(list) {
remove_last_element(list);
do (list)
// call list with one element less
}
Zeitbedarf: Tn = n Tn-1 (Tn = Zeitbedarf für n, n2, T1=1)
Tn =nTn-1 = n  (n-1)  Tn-2 = n  (n-1)  (n-2) Tn-3 = ... = 1 2 3 ... n
 Tn = n!  Laufzeit O(n!) (wirklich viel! Algorithmus inpraktikabel)
2. for i=1 to n {
j=1;
while (j<i) { j = j+2; }
}
Zeitbedarf: Betrachte Anzahl der Zuweisungen für alle i<n:
1 + 2 + 2 + 3 + 3 + 4 + 4 + .... + n/2 + n/2 =
2  (n/2  (n/2+1))/2 - 1 = n/2  (n/2 +1) -1 = n2/4 + n/2 - 1
 Laufzeit O(n2)
Lösung 7.1
Syntax und Semantik
1. Geben Sie Beispiele für
a) lexikalische Strukturelemente: Bezeichner, Literale, Schlüsselworte, ...
b) syntaktische Strukturelemente: Alle Elemente aus „Algorithmenentwurf“
der Programmiersprache C++ an
2. Formulieren Sie die Semantik
a) einer while-Schleife:
siehe Schleife mit vorausgehender Prüfung
b) eines Unterprogrammaufrufes siehe „Block“
1. recherchieren Sie nach weiteren Programmiersprachen
Algol 60, Algol 68, Forth, PL/1, Fortran, Smalltalk, Simula 67, SETL,
Snobol, Cobol, Pascal, Turbo-Pascal, DELPHI, Concurrent Pascal, SPSS,
CLU, Alphard, SDL, Oberon, Oberon-2, Object Cobol, Ada, APL, CDL 2,
Ada 95, Mesa, Modula-2, Chill, BCPL, C, Objective-C, Modula-3, C++,
,Assemblersprachen, Prolog, Prolog II, Eiffel, Beta, Opal, CS,P Hope,
Miranda, Lisp, Common Lisp, PHP, Perl, Scheme, Haskell, Standard ML,
Clipper, Basic, Visual Basic, Java, JavaScript, SQL, Late,x Postscript,
HTML, UML, Z, Act-One, VDM, awk, LEX, YACC, Maschinensprachen,
RPG, Occam, Linda, T Lotus, OPS-5, ...
 werden Sie zu Meta-Programmierern und -Programiererinnen
Lösung 7.2
Reguläre Ausdrücke
1. Geben Sie reguläre Ausdrücke für
a) Integerliterale:
b) while, function, if
[1-9][0-9]* bzw. (1|2|3|4|5|6|7|8|9)(o|1|2|3|4|5|6|7|8|9)*
while usw. bzw. ‘w‘‘h‘‘i‘‘l‘‘e‘ usw.
2. Geben Sie einen regulären Ausdruck zu folgenden Sprachen an:
a) Alle Folgen von Großbuchstaben, die jeden Vokal genau einmal in
alphabetischer Reihenfolge enthält:
KONS = [B-DF-HJ-NP-TV-Z]
{KONS}A{KONS}E{KONS}I{KONS}O{KONS}U{KONS}
b) Alle Dualziffernfolgen, die „001“ nicht als Teilfolge enthalten
(0?1+)*0*
2. Welche Sprachen sind durch die folgenden regulären Ausdrücke
definiert ?
a) (0?|1*)*
b) (0|1)*0(0|1)(0|1)
c) /\*((\*[^/])|[\*])*\*/
alle Binärzahlen, denn (0|1) ist Teilmenge von (0?|1*)
alle Binärzahlfolgen, bei denen die drittletzte Ziffer
existiert und 0 ist
„wohlgeformte“ C-Kommentare
Lösung 7.3
Grammatiken
1. gegeben ist folgende Grammatik G:
G = { N,T,P,S }, N = { A,B,C,S }, T = { a,b,c },
P = { S:=ABC, A:=ABA, C:=CBC, A:=a, B:=b, C:=c }
a) Die Grammatik ist kontextfrei, da auf der linken Seite aller Regeln genau
ein Nichtterminalsymbol steht
b) Beweis durch Ableitung :
S  ABC  ABABC  ABABABC  ABABABCBC  ... : abababcbc
c) Es gibt keine Regel, die ein b vor ein a produziert, daher ist b2a2c3  L(G),
denn in b2a2c3 ist ein b vor einem a.
d) (ab)+c(bc)*
e) Da die Grammatik G kontextfrei ist die Sprache vom Chomsky-Typ-2. Da
sich die Sprache auch als regulären Ausdruck darstellen lässt, ist die
Sprache sogar Chomsky-Typ 3.
f) Ja, denn jede Chomsky-Typ2 bzw. 3 Sprache ist auch vom Chomsky-Typ0
Beispielklausur
 In diesem Kapitel wird ein Beispiel für eine Klausur vorgestellt. Dabei
sind jeweils die Aufgaben und die Lösungen gegeben.
 Beachten Sie
 Diese Beispielklausur erhebt weder in Form, Inhalt noch Umfang einen
Anspruch auf Vollständigkeit.- dies betrifft insbesondere reine
Wissensfragen, die hier etwas vernachlässigt sind.
 Grundsätzlich ist der gesamte in der Vorlesung und den Übungen
behandelte Stoff möglicher Gegenstand der Prüfung
 Vorbereitung
 Arbeiten Sie die gesamten Folien nochmals durch
 Bearbeiten Sie alle Übungsaufgaben nochmals
 Arbeiten Sie das Skript von Herrn Geise durch
 Bearbeiten Sie dessen Übungsaufgaben
Bedenken Sie: In der Klausur sind keine Hilfsmittel zugelassen.
Informatik
 Fehlt in dieser Beispielklausur
a) ...
Information
 Eine Nachrichtenquelle sendet Zeichen aus dem Alphabet
X = {a,b,c,d,e} mit den Wahrscheinlichkeiten p(a)=1/2, p(b)=p(c)=p(d)=p(e)=1/8
a)
b)
c)
d)
e)
Wie groß ist der Informationsgehalt der einzelnen Zeichen
Wie groß ist der Informationsgehalt der Nachricht „abc“
Wie groß ist der mittlere Informationsgehalt einer Nachricht mit 1000 Zeichen
Finden Sie einen möglichst optimalen Code für dieses Alphabet
Angenommen die Wahrscheinlichkeiten wären
p(b)=1/2, p(a)=p(c)=p(d)=p(e)=1/8 .
Wie groß wäre dann die Redundanz Ihres Codes aus Aufgabe d)
 Hamming
a) Codieren Sie die Binärzahl 1000 mit der Hamming-Methode
b) Wieviele Bits können als fehlerhaft erkannt werden ?
c) Wieviele Bits können korrigiert werden ?
Zahlensysteme
 Stellen Sie die Dezimalzahl 7,25
a) Binär
b) Hexadezimal
c) Oktal
dar
 Berechnen Sie im Binärsystem (mit Vollständiger Rechnung)
a) 1100100 : 101
b) Machen Sie schriftlich die Gegenprobe (auch im Binärsystem)
c) 10111 – 1010 (durch Addition des Zweierkomplements)
Zahlensysteme
 Fehlt in dieser Beispielklausur:
a) Gleitpunktzahlen
b) IEEE 754
c) ...
Datenstrukturen
 Gegeben ist folgende Struktur
...
Vorname
Vorname
Vorname
Nachname
Nachname
Nachname
...
a) Definieren Sie Datenstrukturen, mit denen diese Struktur einer zweifach verketteten
Liste repräsentiert werden kann.
b) Begründen Sie, weshalb diese Datenstruktur als „dynamisch“ bezeichnet wird (im
Gegensatz zu statisch)
c) Geben Sie jeweils zwei Gründe für die Verwendung dynamischer bzw. statischer
Datentypen an.
d) Definieren Sie statische Datenstrukturen, mit denen man die oben aufgezeichnete
Struktur möglichst vollständig abbilden kann.
Algorithmenentwurf
 Gegeben ist folgender Algorithmus:
x=a, y=5;
while (x>0)
{
y = y+1;
x = x-1;
}
a) Formen sie die while Schleife in eine repeat-Schleife um
b) Bilden Sie die Funktion dieses Algorithmus‘ ohne Schleifen, mit Hilfe von Sprüngen
und Marken nach
Algorithmenentwurf
 Fehlt in dieser Beispielklausur:
a)
b)
c)
d)
Weitere Umformungen
Blockung
Umwandlung Rekursion/Iteration
...
Berechenbarkeit
 Beweisen Sie mit Hilfe einer Turing-Maschine, dass f: N  N mit: f(x) ist
Binärkomplement von x berechenbar ist.
a) Geben Sie dabei an:





Alphabet
Bandinschrift (mit Codierverfahren)
Kopfposition
Zustände (mit dem Startzustand und den Endzustände)
Zustandsübergänge
b) Zeichen Sie für eine Zahl das Turingband vor- und nach Ausführung des
Turingprogrammes
Korrektheit
 Tausch zweier Variablen
a) Entwerfen Sie einen Algorithmus zum Vertauschen der Werte zweier
Variablen (vom Typ integer)
 Vorbedingung: x=a, y=b
 Nachbedingung: x=b, y=a
b) Beweisen Sie die Korrektheit Ihres Algorithmus
 Gegeben sei folgender Algorithmus:
x=3, y=5;
while (x>0)
{
y = y+1;
x = x-1;
}
a) Was macht dieser Algorithmus ?
b) Beweisen Sie Ihre Antwort für Frage a) mit Hilfe der Hoare'schen Logik
Komplexität
 Fehlt in dieser Beispielklausur:
a)
b)
c)
d)
Fragen zu den Konstanten c und n0
Beispiele für O(...)
Bestimmung des Aufwandes für iterativen/rekursiven Algorithmus
...
Reguläre Ausdrücke
 gegeben ist folgender regulärer Ausdruck R (in UNIX-Notation):
[abc]*d[abc]+ (mit Alphabet  = {a,b,c,d} )
a) formulieren Sie den Ausdruck in die „klassische“ Notation für reguläre
Ausdrücke um.
b) Geben Sie 2 Worte aus L(R) deren Länge jeweils genau 10 Zeichen
betragen
c) Geben Sie zwei Worte aus * an, die nicht in L(R) sind
d) Konstruieren Sie einen indeterministischen endlichen Automaten A mit
L(A)=L(R)
 Konstruieren sie reguläre Ausdrücke (in UNIX-Notation) für
a) Hexadezimalzahlen
b) Eigennamen bestehend aus optionalen Titeln, Vor- und Nachnamen
(eventl. Doppelnamen, keine Beachtung von Umlauten)
 Beispiele.: Prof. Dr. Peter Kneisel, Sabine Mustermann, Dr. Kloebner, KarlHeinz Müller-Lüdenscheid)
c) Lall-Sprache: Bestehend aus l‘s, die durch Vokale miteinander-Verbunden
sind
 Beispiele: lal, lala, lelalilu, lelelalal
Endliche Automaten
 Gegeben ist folgender endlicher Automat A
z0
b
a
z1
e
z2
b
a
z3
a) Von welchem Typ ist dieser Automat:
Ist dies ein NEA oder ein DEA, begründen Sie Ihre Antwort
b) Formen Sie den Automaten in den anderen Typ so um, dass immer noch
die gleiche Sprache akzeptiert wird.
c) Welches sind die Symbole, die der Automat verarbeitet ?
d) Geben Sie die Übergangsfunktion d an
e) Formulieren Sie einen regulären Ausdruck R mit L(R) = L(A)
Grammatiken
 Fehlt in dieser Beispielklausur
Lösung: Information
 Eine Nachrichtenquelle sendet Zeichen aus dem Alphabet
X = {a,b,c,d,e} mit den Wahrscheinlichkeiten p(a)=1/2, p(b)=p(c)=p(d)=p(e)=1/8
a) h(a) = -ld(1/2) = 1bit. h(b)=h(c)=h(d)=h(e)=-ld(1/8)=3bit
b) 1bit + 3bit + 3bit = 7 bit
c) 1000 x Mittlerer Informationsgehalt: H(x)=p(xi)h(xi) =
1000 x ( 1/2x1 + 1/8x3 + 1/8x3 + 1/8x3 + 1/8x3 )bit = 1000 x 2bit = 2000 bit
d) Nach Huffmann: p(de)=1/4, p(bc)=1/4, p(debc)=1/2, p(a)=1/2). p(abcde)=1
also z.B.: a=1, b=000, c=001, d=010, e=011
e) Redundanz = L(x)-H
l(x)=1bit , l(b)=l(c)=l(d)=l(e)=3bit (entsprechend der Codierung in d.)
L(x) = p(xi)l(xi) = (0,125x1 + 0,5x3 + 0,125x3 + 0,125x3 + 0,125x3)bit = 2,75 bit
h(b) = 1bit, h(a)=h(c)=h(d)=h(e)=-ld(1/8)=3bit
H(x) = p(xi)h(xi) = (0,5x1 + 0,125x3 + 0,125x3 + 0,125x3 + 0,125x3 )bit = 2 bit
Redundanz = L(x)-H = 2,75bit – 2bit = 0.75 bit
 Hamming
a) 100P0PP (Relevant: Bit 3,5,7)  100P0P1 (even Parity: also 1 ergänzen)
100P0P1 (Relevant: Bit 3,6,7)  100P011 (even Parity: also 1 ergänzen)
100P011 (Relevant: Bit 5,6,7)  1001011 (even Parity: also 1 ergänzen)
b) Der Hamming-Abstand D ist 3bit, es können D-1 = 2bit Fehler erkannt
werden
c) Es können (D-1)/2 = 1bit Fehler korrigiert werden.
Lösung: Zahlensysteme
 Dezimalzahl 7,25
a) Vorkommateil:
7 : 2 = 3 Rest: 1
3 : 2 = 1 Rest: 1
1 : 2 = 0 Rest: 1 -> 111
Binärzahl: 111.01
b) 0111,01002 = 7,416 (7 * 160 + 4 * 16-1)
c) 111,0102 = 7,28 (7 * 80 + 2 * 8-1)
Nachkommateil
2 · 0,25 = 0,5 --> Ziffer: 0
2 · 0,5 = 1
--> Ziffer: 1
->0,01
 Berechnung
 1100100 : 101 = 10100
101
--101
101
--000
10100 x 101
10100
00000
10100
------1100100
 10111 – 1010
10111 - 01010 auf gleiche Längenbringen 1
10111 + 10110 Binärkomplement 10101+ 1
= 101100
Lösung: 1101 Überlauf weggelassen
Lösung: Datenstrukturen
 Doppelt verkettete Liste
a) Person : record
{ vorname : array[1..64] of char;
nachname: array[1..64] of char;
prev
: *Person;
next
: *Person;
}
b) Man kann aus diesen Strukturen beliebig lange Ketten von Personen
bilden
c) Pro: Dynamisch: Verwaltung von Objekten, deren Anzahl zur
Entwicklungszeit nicht bekannt ist. Speicherverbrauch nur für die Objekte,
die tatsächlich zur Laufzeit existieren.
Pro Statisch: Einfach in der Realisierung, schnell in der Bearbeitung
(Fehlerunanfälliger)
d) Person : record
{ vorname : array[1..64] of char;
nachname: array[1..64] of char;
}
Personeliste: array[1...65534] od Person;
Lösung: Algorithmenentwurf
 Umformung der while-Schleife:
a) Als repeat-Schleife:
x=a; y=5;
if (x>0)
{
repeat
{
y = y+1;
x = x–1;
} until (x<=0)
}
b) Sprünge und Marken
x=a; y=5;
1: if (x<=0) goto 2
y = y+1;
x = x–1;
goto 1;
2: ...
do
{
y = y+1;
x = x-1;
} while (x<=0}
x=a; y=5;
1: if (x>0)
{
y = y+1;
x = x–1;
goto 1
}
2: ...
Lösung: Berechenbarkeit
 Definiere eine Turing-Maschine, die beliebige binäre Ziffernfolgen
bitweise invertiert.
 Die Turing-Maschine:





Alphabet : {_,0,1},
Bandinschrift: Zahl, codiert als Binärzahl, alles andere „_“
Kopfposition: links neben der Binärzahl
Zustände: {q0, q1,q2}, Startzustand. q0, Endzustände:{q2}
Zustandsübergänge:
A  Q  A  Q  {r, l}
_,q0  _,q0,r
0,q0  1,q1,r
1,q0  0,q1,r
0,q1  1,q1,r
1,q1  0,q1,r
_,q1  _,q2,r
 Das Turing-Band vor und nach Abarbeitung des Turing-Programmes für die
Zahl: 44
1 0 1 1 0 0
0 1 0 0 1 1
Lösung: Korrektheit
 a) und b)
z : integer
{ x=a,y=b }
z=y; {x=a,y=b,z=b}
y=x; {x=a,y=a,z=b}
x=z; {x=b,y=a,z=b  x=b,y=a} q.e.d
 Beweis durch Anwendung der Hoare‘schen Logik:
a) Der Algorithmus liefert für y den Wert 8  Nachbedingung Q: (y=8)
b) x=3, y=5; {x=3, y=5}
{ INV: y=8-x  x0 }
while (x>0)
{
{ INV  x>0  (y+1)-1=8-x  x0  x>0 }
y = y+1;
{ y-1=8-x  x0  x>0  y=9-((x-1)+1)  (x-1)+1>0 }
x = x-1;
{ y=9-(x+1)  x+1>0  y=8-x  x0
 INV}
}
{ INV  x0  y=8-x  x=0  y=8 = Q } q.e.d.
Lösung: Reguläre Ausdrücke
 gegeben ist folgender regulärer Ausdruck R (in UNIX-Notation):
[abc]*d[abc]+ (mit Alphabet  = {a,b,c,d} )
a)
b)
c)
d)
(a|b|c)*d(a|b|c)(a|b|c)*
abcabcdabc
abddab. abcabcaabbccd
NEA: z.b.
z0
e
a,b,c,e
z1
d
z3
e
a,b,c
z4
 Konstruieren sie reguläre Ausdrücke (in UNIX-Notation) für
a) [1-9A-F][0-9A-F]*
b) (Prof\.)?(Dr\.)?([A-Z][a-z]*(\-[A-Z][a-z])?)? ([A-Z][a-z]*(\-[A-Z][a-z])?)
c)VOKAL = [AEIOU]
l(<VOKAL>l)*<vokal>?
Lösung: Endliche Automaten
 Gegeben ist folgender endlicher Automat A
b
z0
a
z1
b
z2
e
z3
a
a) Dies ist ein indeterministischer endlicher Automat, da es einen e-Übergang
gibt.
b) NEA  DEA, z.b.:
z0
b
a
z2
a
z3
a
b
z2
c) a,b
d) d = { (z0, a, z1), (z1, b, z0), (z1, e, z1), (z2, a, z3), (z3, b, z2) }
e) a(ba)*a(ba)*
Herunterladen