Sieht gut aus.
Gut, dann können wir mit der Übung anfangen.
Die erste Aufgabe beschäftigt sich mit endlichen Automaten und
Grundlagen, einige Grundbegriffe, die zu diesen geklärt werden sollen.
Zunächst mal die Frage, wozu setzt man endliche Automaten ein im
Rahmen der Informatik?
Das ist Analyse,
Beschreibung und Realisierung von Systemen.
Sie haben einiges davon im Übungsblatt dann auch getan, indem Sie eben
genau diese Automaten an verschiedenen Stellen eingesetzt haben, auch
für die Umsetzung später im Rahmen eines der Java-Programme.
Die einzelnen Bestandteile der endlichen Automaten, da ist zu nennen
natürlich die Zustandsmenge
inklusive des Startzustands,
dann ein Zeichenvorrat und die Menge der Zustandsübergänge.
Das sind die Sachen, die in allen endlichen Automaten auftreten.
Es gibt noch ein paar, die ich jetzt hier hinzufügen möchte, die Sie
nicht hätten unbedingt schreiben müssen.
Das ist zum Beispiel der Ausgabezeichenvorrat,
der üblicherweise nicht der gleiche ist wie der Zeichenvorrat.
Es ist allerdings auch nicht verboten, dass man die gleichen Zeichen
für die Ein- und Ausgabe verwendet.
Es ist bloß geschickt, wenn man da unterschiedliche verwendet, um
einfach Verwirrung zu vermeiden.
Weiterhin, also das gibt es nur bei Mealy und Moore Automaten und die
Menge von Endzuständen,
die gibt es dann natürlich nur bei Akzeptoren.
Also das wären eben Sachen, die nur bei spezifischen endlichen
Automaten auftreten.
Die anderen Dinge sind auch bei allen endlichen Automaten notwendig.
Der Unterschied zwischen Moore und Mealy Automat ist welcher?
Beim Mealy Automat haben wir die Ausgabe auf den Übergang,
Zustandsübergang.
Beim Moore Automat beim Erreichen eines Zustands.
Alles nicht weiter schwierig.
Ich denke mal, die Aufgabe sollte eigentlich auch recht gut lösbar
gewesen sein.
Solche Sachen sollte man auch einigermaßen im Kopf haben, damit man
sowas auch in der Klausur machen kann, wo man nicht unbedingt dann ein
Skript da hat, wo man nachschlagen kann.
Kommen wir zur nächsten Aufgabe, zum SchnipoStar.
Dabei ging es darum, einen Automaten für diese Aufgabe zu entwickeln,
der eben genau diese drei Menüs, oder die Ausgabe dieser drei Menüs
erfasst.
Die Eingabe mit Geld, was man einschmeißt, mit ein- und zwei-Euro
-Stücken.
Und später soll das Ganze dann auch noch realisiert werden in Form
eines Java-Programms.
Das war eine etwas umfangreichere Aufgabe.
Die Musterlösung, die wir hier haben, sieht so aus, dass wir die
Zustände beschreiben, wie viel Geld im Automaten drin ist.
Ich denke mal, das ist hoffentlich relativ naheliegend, dass man auf
diese Idee kommt.
Das heißt, wir beginnen im Zustand Q0, wo wir 0 Euro drin haben, und
erhöhen das sukzessive.
Ich habe hier mal die Legende aufgeschrieben, die wir dann im Rahmen
dieses Graphen verwenden, nämlich also ST sei als Eingabe, wenn ich
das Studiemenü anfordere, und auch als Ausgabe in dem Fall, wenn ich
es zurückbekomme, und analog die anderen Dinge.
Der erste Punkt ist klar, unser Startzustand ist Q0.
Am Anfang ist der Automat leer, hat kein Geld eingeschmissen.
Was kann ich dann machen?
Ich kann 1 Euro Münzen einschmeißen, dabei gibt es keine Ausgabe, ich
komme bloß jeweils in einen nächsthöheren Zustand.
Man hätte hier natürlich auch an der Ausgabe reinschreiben können, der
jeweils den Zustand, also der erreicht wird, praktisch zum Beispiel,
dass jetzt hier dann 1 Euro sich im Automat befindet, hier, dass sich
2 Euro drin befindet oder ähnliches.
Weiterhin kann ich 2 Euro Münzen reinschmeißen.
Damit ergänze ich den Automaten dann in dieser Form, das heißt, ich
komme von Q0 auf Q2, von Q2 auf Q4, Q1 auf Q3 und so weiter.
Es war ja der Punkt, wenn über 4 Euro drin sind, werden weitere Münzen
nicht mehr angenommen, das heißt, wir gehen bis zur Q4 mit den 1 Euro
Münzen und mit 2 Euro Münzen können wir bis auf Q5 kommen, da wir eben
dort von Q3 mit einem 2 Euro Stück hinspringen können, aber danach
darf eben nichts mehr weiter passieren, das heißt also, wenn weiteres
Geld eingeschmissen wird, wird es dann sofort wieder ausgegeben, das
kommt dann gleich noch.
So, wenn ich das jetzt habe, das war jetzt praktisch das Geld
einschmeißen, was jetzt noch hinzukommt, ist, wenn man sich ein Menü
holt, also dieses Extra-Spar ist ja das billigste Menü gewesen, das
bringt uns wieder zurück einen Zustand weiter unten, da sieht man eben
auch, der gibt praktisch als Eingabe hier X und bekommt als Ausgabe
ein solches Menü zur Verfügung gestellt.
So, das Ganze gibt es natürlich auch für das Studi-Menü, das ist ja
etwas teurer, kostet 2 Euro, dementsprechend springe ich da immer zwei
Zustands -Ebenen praktisch nach unten
und das Luxus-Menü, das kann nur vom Zustand 4 und Zustand 5 aus
überhaupt erreicht werden, weil sonst ist nicht genügend Geld im
Automaten drin.
So, jetzt gibt es noch die Möglichkeit, wieder zurückzusetzen, dass
man eben sagt, ich möchte mein Geld zurückhaben, das war hier mit R,
man sieht es auch, ich habe es an anderen Stellen auch hier ergänzt,
das heißt, wenn ich im Zustand 2 bin und R drücke, kriege ich eben 2
Euro wieder raus, naheliegend.
Soweit der Automat.
Jetzt gibt es da noch eins, und zwar den Punkt, das war nicht
unbedingt gefordert, das war nicht unbedingt ein vollständiger Automat
in dem Fall, in dieser Aufgabenstellung gefordert, aber
sinnvollerweise sollte man das auch machen, das heißt, wenn man eben
in diesen Zuständen sich befindet, wo nicht genügend Geld vorhanden
ist, dann soll eben als Ausgabe nichts rauskommen, egal welches Menü
man wählt.
Hier ist es eben so, das Geld reicht nicht für die Menüs Extra-Spar
und Studi, dementsprechend muss er da eben in dem Zustand bleiben und
hat keine Ausgabe.
Beziehungsweise die Ausgabe ist nichts, also er sagt, er kann es nicht
ausgeben, weil nicht genügend Geld vorhanden ist.
Auch hier hätte man anstelle von N ein Y verwenden können, dass eben
einfach gar keine Ausgabe erfolgt.
Sinnvollerweise sollte natürlich unser Automat sagen, dass er nichts
ausgibt, beziehungsweise warum er nichts ausgibt.
Gut, das war eigentlich der Automat.
Sieht jetzt etwas wüscht aus.
Wie realisiert man das als Java-Programm?
Ich habe mir jetzt überlegt, soll ich Ihnen hier fünf bis zehn Folien
mit Java-Code zeigen, das bringt uns nicht wirklich wesentlich weiter.
Deshalb mache ich nur einen kleinen Ausschnitt und erkläre Ihnen, wie
das Grundkonzept von dem Programm aussieht.
Die Idee ist, dass wir zunächst mal für jeden Zustand eine Methode
machen.
Das heißt, es gibt eine Methode Q0, Q1 und so weiter.
Und jede Methode gibt, sobald man reingibt, zunächst mal den aktuellen
Guthabenstand aus.
Das war, wie gesagt, nicht unbedingt gefordert, aber ist natürlich
ganz nützlich.
Sie liest ein Zeichen ein aus dem Eingabezeichenvorrat und gibt die
entsprechende Ausgabe aus.
Und sofern mit dieser Eingabe ein Zustandswechsel erfolgt, ruft es
danach den entsprechenden Folgezustand aus.
Das ist eigentlich die Idee.
Und die Main-Methode selbst ist dann sehr, sehr kurz.
Die ruft nämlich einfach bloß Q0 auf.
Das ist unser Startzustand, das heißt, er geht zuerst in den
Startzustand und liest da ein.
Ich habe jetzt mal eine dieser Methoden mir geschnappt, aber um die
demonstrieren zu können, habe ich hier den Automaten noch mal etwas
anders gestaltet.
Ich habe nämlich hier die Menüs mit einfachen Buchstaben bewertet.
Besetzt ist es zwar nicht so leicht lesbar, hat aber den Vorteil, dass
es sich leichter im Programm umsetzen lässt.
Das heißt, die Eingaben sind hier eben A, B und C.
Das heißt, ich brauche bloß einen Charakter einlesen und muss nicht
einen String einlesen.
Das ist im Endeffekt der ganze Witz, weshalb wir das so gemacht haben.
Gut, ich habe mir die Methode Q1 rausgesucht.
Hätte im Prinzip auch jeder andere nehmen können.
Erster Punkt, wie gesagt, ergibt aus, wir haben einen Euro in unserem
Automaten.
Danach liest er Zeichen ein, und zwar immer ein Zeichen.
Und dann überprüft er natürlich, ob dieses Zeichen sich in dem
korrekten Zeichenvorrat befindet.
Und liest immer wieder ein, bis eben ein korrektes Zeichen des
Eingabezeichenvorrats eingegeben wurde.
Also korrekte Eingaben sind eben 1 und 2, wenn ein Geldstück
eingegeben wird.
ABC, wenn eben ein Menü ausgewählt wird.
R für Rückgabe und Q, um das Ganze abzubrechen.
Gut, dann, hier ist das Ganze durch eine verschachtelte IF-Anweisung
realisiert.
Überprüft er, wenn es eine 1 ist.
Wenn es eine 1 gewesen ist, er befindet sich im Zustand 1, muss er
danach in Zustand 2 gehen.
Klar.
Wenn es ein 2 ist, dann muss er vom Zustand 1 in Zustand 3 gehen.
Ist auch klar.
Wenn es ein R ist, muss er den Euro, der momentan drin ist, wieder
zurückgeben und in Zustand Q0 gehen.
Wenn es ein A oder B ist, muss er sagen, nee, so viel Geld habe ich
leider nicht.
Das Gericht kostet mehr als 1 Euro und bleibt in dem Zustand, in dem
es vorher schon war, also in Q1.
Und wenn es ein C ist, gibt er eben das Menü aus und geht wieder
zurück in den Zustand Q0.
Und analog werden im Prinzip die anderen auch realisiert.
Man hätte hier natürlich auch anstelle der IF-Kaskade eine Case
-Anweisung verwenden können.
Grundsätzlich, um das vielleicht etwas kürzer zu schreiben.
Und im Endeffekt war das eigentlich schon das ganze Programm.
Also es war nicht allzu schwierig, es war auch die Frage im Forum
aufgekommen, ob man unbedingt einen Zustand durch eine Methode
repräsentieren muss.
Muss man nicht unbedingt, aber das war eigentlich als Hilfestellung
gedacht, wie man praktisch an die Sache herangehen kann, um eben
einfach die Sache realisieren zu können.
Wenn man es so sieht, denke ich, kann man es jetzt ganz einfach
runterprogrammieren.
Gut, kommen wir zu den römischen Zahlen.
Da sollte die Sprache betrachtet werden, die die römischen Zahlen von
1 bis 20 enthält.
Und es sollte eine Chomsky-Grammatik vom Typ 3 für diese Sprache
angegeben werden und danach ein vollständiger deterministischer
Akzeptor, der mit 8 Zuständen auskommt.
Das ist eine sehr schöne Aufgabe, weil nämlich nur sehr wenig Lösungen
korrekt sind am Ende.
Weil wir durch Vollständigkeit, Determinismus und die Anzahl der
Zustände die Anzahl der möglichen Lösungsautomaten drastisch
eingeschränkt haben.
Gut, wie gehen wir an die Sache ran?
Wie sieht die Chomsky-Grammatik aus?
Die grundlegenden Sachen habe ich hier jetzt schon mal vorbereitet,
also die Grammatik und die Nicht-Terminalmenge, die Terminalmenge oder
das Alphabet sind schon vorgegeben.
Ich mache mir hier jetzt noch eine kleine Hilfe hin, nämlich die
Zahlen, die ich alle erfassen möchte.
Mache ich deshalb, dann kann ich nachher nämlich wegstreichen und sehe
dann, ob alles drin ist.
Und das ist dann die tatsächliche Produktionsmenge, die wir dafür
brauchen.
Oder das ist eine Lösung.
Jetzt schauen wir mal, ob die stimmt.
Gucken wir zunächst mal, also von A, vom Startzustand können wir, vom
Axiom können wir zur 1, zur V und zum X gehen.
Ups, da ist es.
Na toll.
Wir können weiterhin zu 1b.
1b gibt wieder hier 1, V oder X.
Das heißt, ich habe ein 1, 1 weg, ich habe ein 1, V weg und ich habe
ein 1, X weg.
Wunderbar.
Und dann können wir noch zum 1c gehen.
Das wären dann drei senkrechte Striche.
Gut.
Dann können wir von A nach Vd gehen.
Vd können wir zur 1, also das wäre V1.
Oder 1e, das heißt, das wäre V... und hier haben wir wieder eine 1,
das wäre V2.
Und wir können zur 1c gehen, das wäre V3.
Gut.
Und dann können wir zur Xf gehen.
Xf sieht eigentlich genauso aus wie A, das heißt, es ist das gleiche
wie A, bloß ein X da vorne dran.
Ja.
Und wir haben, wie wir hier sehen, die obere Hälfte fertig und die
untere Hälfte sind genau die, die ein X vorne dran haben.
Das heißt, die haben wir auch erledigt.
Diese Produktionsmenge würde das Problem lösen.
Es gibt aber noch eine viel einfachere.
Kann es jemand mir die nennen?
Naja, einfach aufzählen.
Das wäre auch korrekt gewesen.
Stimmt, es ist kein Chomsky 3.
Schade.
Wäre eine schöne Lösung gewesen.
Aber Sie haben recht, es ist leider keine Chomsky 3 Grammatik, von
daher.
Okay, dann schauen wir uns mal an, wie der Akzeptor dafür aussieht.
Wir haben, wie gesagt, acht Zustände.
Drunter wird es wahrscheinlich schwierig.
Q0, unser Startzustand.
Zunächst mal können wir mit 1, nochmal 1 oder nochmal 1, die ersten
drei Zahlen hier abdecken.
Und wir müssen natürlich dafür sorgen, dass jeweils Q1, Q2 und Q3
Endzustände sind.
Weiter können wir von Q1 V und X ableiten.
Das heißt, es wäre 1V und 1X.
Nächsten Schritt können wir die Worte nehmen, die mit V beginnen.
Das ist V1, V selbst, V1, V2 und V3.
Hier sieht man, ich hätte natürlich eigentlich auch hier nochmal einen
Zustand verwenden können.
Aber das mache ich nicht, um eben Zustände einzusparen im Endeffekt.
Gut, dann können wir natürlich ein X beziehungsweise zwei X nehmen.
Was können wir jetzt noch?
Alles, was wir schon hatten,
was mit X anfängt.
Das heißt, wir gehen hier mit einem 1 rüber und können dann 1, 1 oder
noch ein V hinten dranhängen.
Wir können hier sogar noch ein X hinten dranhängen, das ist ein
bisschen unglücklich.
Gut, und wir können alternativ hier über V gehen, das heißt XV, das
wäre dann die untere Reihe im Prinzip.
Was wir jetzt noch nicht haben, ist der Fehlerzustand, weil wir ja
einen vollständigen Automaten haben wollten, müssen wir noch alle
nicht zulässigen Angaben in einen anderen Zustand ableiten, der kein
gültiger Endzustand ist.
Und damit haben wir jetzt einen Akzeptor geschaffen, der mit 8
Zuständen auskommt und genau die Zeichen enthalten darf, die auch in
unserem Alphabet gefordert waren.
Wer ist auf diesen Akzeptor oder auf einen ähnlichen Akzeptor
gekommen?
Ah ja, sieht doch gut aus.
Sehr schön.
Das war ein bisschen mit probieren, denke ich, auch verbunden.
Dann kommen wir zum regulären Ausdruck.
Es soll ein regulärer Ausdruck für die Zahlen zwischen 0 und 99
erstellt werden.
Und führende Nullen sollen nicht akzeptiert werden.
Das heißt also 00, 01, sowas soll nicht gelten.
Wichtig hier in dem Zusammenhang, das war leider etwas unglücklich
formuliert, man kann natürlich das auch so verstehen, dass wir die
Zahlen zwischen 1 und 98 beschreiben sollen.
Wenn Sie das so gemacht haben, ist das auch in Ordnung, wird auch als
korrekt gewertet, sofern die Lösung korrekt ist.
Grundsätzlich war aber das gemeint zwischen 0 und 99 einschließlich.
Der Ausdruck sieht folgendermaßen aus, oder ein möglicher Ausdruck.
Wir machen zunächst mal die 0, weil die ein bisschen ein Sonderfall
ist.
Sagen dann 1, 2, 3, 4, 5 und so weiter, 6, 7, 8 und 9.
Wichtig, keine 0 dabei.
Und dann 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Wenn ich das so hinschreibe, darf keine Zahl mit einer 0 anfangen,
außer es ist die 0.
Das ist die einzigste.
Das ist nämlich hier dieser Ausnahmefall.
Ansonsten fangen die Zahlen mit 1 bis 9 an.
Und die zweite Ziffer darf dann aber zwischen 0 bis 9 sein.
Diese Lösung ist aber noch nicht ganz korrekt, weil wir können damit
nur zweistellige Zahlen beschreiben.
Das heißt, wir machen hier ein Plus-Epsilon noch dazu.
Das wäre eine Lösung, die wir hier hinkommen.
In dem Zusammenhang möchte ich auf eine Sache hinweisen.
Dieses im Sinne von oder verwendete Plus hier.
Es ist ein Pluszeichen nach der Notation, die in der Vorlesung
eingeführt wurde und kein senkrechter Strich, wie er an anderen
Stellen verwendet wird.
Das ist ganz wichtig, damit da eben bezüglich der Notation keine
Fehler reinkommen.
Bitte beachten Sie das.
Gut, das war eine recht einfache Aufgabe.
Jetzt kommen wir dann zu den ersten Programmieraufgaben im Bereich der
Objektorientierung.
Da kann ich nur den Tipp geben, probieren Sie es aus.
Ich kann Ihnen zwar jetzt einige Sachen vorführen, aber ich denke mal,
da muss man selbst ein bisschen reinkommen, sofern man das Prinzip der
Objektorientierung nicht schon kennt.
Hier sollten zunächst mal Computer erstellt werden, die Attribute für
Prozessorgeschwindigkeit, Arbeitsspeichergröße besitzen.
Und dann soll man sich noch drei weitere Attribute überlegen.
Das habe ich hier unter die Klasse Computer zusammengefasst.
Danach soll eben in der Main-Methode der Klasse Computer Management
zwei Objekte der Klasse Computer erstellt werden.
Und denen sollen Werte zugewiesen werden, den Attributen dieser
Computer, und die sollen anschließend ausgegeben werden.
Das wird in den folgenden Folien dann beschrieben.
Die Klasse Computer ist relativ überschaubar und einfach.
Wir haben zunächst mal die vorgegebenen Attribute hier, CPU Speed und
Memory Size.
Und wir haben drei andere Attribute, Double Disk Size, also die Größe
der Festplattenkapazität, ein Boolean, ob es sich um einen Notebook
handelt, und ein String, der den Computernamen enthält.
Sie können natürlich da auch beliebige andere Attribute deklariert
haben, das hier ist jetzt beispielhaft in dem Fall aufgeführt.
Wie sieht das Ganze dann aus, der Aufruf im Rahmen des
Computermanagements?
Dort in der Klasse Computermanagement habe ich mir hier jetzt mal die
Methode Main herausgeholt, in der zunächst mal ein Computer, die 71
IPU, erzeugt wird.
Das ist rein zufällig der gleiche Name wie der Computer, auf dem das
IPU läuft.
Der wird eben erzeugt und mit den Werten belegt, die annähernd
realistisch sind.
Und der Name des Rechners ist auch Info 1 Web Server, das ist im
Endeffekt tatsächlich unser Server, der bei uns läuft, auf den Sie
zugreifen, wenn Sie sich das IPU anschauen wollen.
Es ist kein Notebook nebenbei, naheliegenderweise.
Weiterhin haben wir einen Laptop, den wir als Laptop 1 bezeichnet
haben.
Gut, das ist vielleicht ein nicht unbedingt Semantik tragender Name,
aber ist auch in Ordnung.
Der ähnliche Leistungsdaten aufweist, der dann tatsächlich ein
Notebook ist und eben den Namen Laptop 1 trägt.
Zur Ausgabe dieser Attribute wird dann das Show Attributes, die Show
Attributes Methode verwendet, die ich auf der nächsten Folie dann
vorstelle.
Show Attributes, hier haben wir es, bekommt als ein Parameter ein
Computer übergeben.
Dieser Computer wird ausgegeben, einfach indem er auf den Namen
zugreift, auf die Geschwindigkeit und so weiter.
Und eben hier noch eine kleine Verzweigung haben wir hier noch
eingebaut gehabt, ob sich eben bei dem Rechner um ein Notebook handelt
oder nicht und dementsprechend gibt er eben unterschiedliche Ausgaben
aus.
Alles nicht weiter schwierig, soweit.
Dann kommen wir zur nächsten Aufgabe, die im Prinzip darauf aufsetzt
und den Computer um eine Methode, oder um zwei Methoden erweitert.
Die einen Vergleich ermöglichen und zwar einmal auf Ebene der Objekte
und einmal auf Ebene der Attribute auf Gleichheit Überprüfung
durchführt.
Das wird die Method CheckForEqualObjects und CheckForEqualAttributes.
Das sind die beiden Methoden, die ich dann auch gleich zeigen werde.
Und dann sollen Sie in der Aufgabe 1.3.1, also die Main-Methode
ergänzen, indem Sie eben diese Methoden dann auch mal nutzen und
verwenden.
Und eben die Computer vergleichen, die entstehen, beziehungsweise dann
auch sollen Sie mit einem einzigen Befehl alle Werte eines Computers
dem anderen zuweisen.
Das zeige ich dann auch gleich, wie man das machen kann.
Hier haben wir jetzt die Methode CheckForEqualObjects und da wird eben
if this gleich pc return true, else return false.
Ist recht einfach.
Wie könnte man diese Methode noch kürzer schreiben?
Ganz genau.
ist gleich pc
Hat dann den Vorteil, dass es etwas kürzer ist, aber vielleicht nicht
mehr ganz so leicht beständig.
Muss man sehen.
Analog, CheckForEqualAttributes, da sollen ja nur die fest
vorgegebenen Attribute verglichen werden, weil bei den anderen wussten
wir ja nicht, welche sie gewählt haben.
Das heißt, hier wird überprüft, ob die CPU-Speed und die Memory-Size
gleich sind.
Wenn das der Fall ist, gibt er true zurück.
Wenn das nicht der Fall ist, gibt er false zurück.
Analog könnte man hier auch dieselbe Abkürzung verwenden, indem man
einfach sagt return diesen Ausdruck.
Gut, jetzt kommen wir zur Aufgabe, zur Main-Methode, wo diese beiden
Methoden aufgerufen werden.
Zunächst mal, ich gehe jetzt mal davon aus, dass die Computer
deklariert wurden analog zur vorangegangenen Aufgabe und vergleiche
hier nur.
Das heißt, ich rufe diesen CheckForEqualObjects auf und wenn das eben
true zurückliefert, sind die beiden Computer identisch.
Wenn es false zurückliefert, sind sie nicht identisch, sind sie
verschieden.
Auf Ebene der Attribute wird eben auch dieser Vergleich durchgeführt.
Sind die identisch ausgestattet oder sind sie verschieden
ausgestattet?
Alle Werte des einen PCs dem anderen PC zuweisen, da kann man zum
Beispiel dem zweiten PC den ersten PC zuweisen.
Das heißt, Laptop1 gleich die 71iPo.
Dann zeigen sie tatsächlich beide auf das gleiche Objekt.
Und wenn ich in dem Fall dann die Sache aufrufe, dann kommt eben raus,
die beiden Computer sind identisch.
Sie haben nicht nur die gleichen Werte, sondern es ist tatsächlich
auch das gleiche Objekt, was dahinter steckt, was dann hinter der
Verzeigerung sich verbirgt.
Dann kommen wir zur nächsten Aufgabe, da geht es darum, dass man dann
jetzt nochmal die Klasse etwas nutzt, um etwas aufwendigere
Geschichten damit zu treiben, um eben einen ganzen Computerraum zu
simulieren im Prinzip.
Mit 25 Rechnern und diese sollen zunächst mal initialisiert werden,
ausgegeben werden, was für Rechner wir dann haben.
Und im zweiten Punkt sollen diese dann aufgerüstet werden.
Das heißt, die ersten zehn Rechner sollen aufgerüstet werden, indem
der Arbeitsspeicher verdoppelt wird.
Beim 15.
Rechner ist der Prozessor defekt und das heißt, dort wurde dieser
Prozessor ausgetauscht und muss dann eben mit einem neuen Prozessor
gelegt werden, der die Geschwindigkeit von 2,5 Gigahertz hat.
Erstellen wir 25 Computer.
In unserem Programm geht es viel einfacher als in der Realität.
Wir müssen uns einfach zunächst mal ein Array erzeugen, in das wir
eben diese 25 Computer unterbringen können und müssen dann jeweils
dieses Array durchlaufen und für jeden Eintrag in dem Array einen
neuen Computer erzeugen und diesen dann entsprechend mit dem Namen
besehen.
In dem Fall haben wir den Namen eben zusammengesetzt, dass auch die
Bezeichnung mit hochgezählt wird, dass die anderen Werte eben
vordefiniert werden und das Ganze soll eben für alle Computer
durchgeführt werden.
Ist nicht weiter kompliziert und im zweiten Schritt sollen dann als
Ergebnisse praktisch die Attribute wieder ausgegeben werden.
Das ist jetzt auch nicht besonders interessant, was dann da rauskommt,
weil es sind ja 25 gleiche Computer.
Das Einzige, wo sie sich unterscheiden, ist der Name in unserem
konkreten Fall, weil wir einen Namen noch als Identifier im Prinzip
hinzugenommen haben.
Das Aufrüsten der Computer funktioniert dann auch in dieser Form, dass
man zunächst mal hingeht und den Speicher verdoppelt.
Haben wir hier mit einer Kurzschreibweise realisiert, wo wir die
ersten zehn Computer durchlaufen, also von 0 bis 9 und diese da den
Speicher verdoppeln und anschließend wird noch beim 15.
Computer, also weil wir ja von 0 bis 24 durchnummerieren, hier beim PC
14 die CPU noch aktualisiert und eben mit diesem Wert belegt und
anschließend werden die Attribute wieder ausgegeben, wie gehabt.
Gut, das waren dann die wesentlichen Punkte zum Übungsblatt.
Kommen wir zum nächsten Übungsblatt.
Oder gibt es jetzt hier noch Fragen zu diesen Aufgaben?
Keine Fragen.
Gut, dann gehen wir zum nächsten Übungsblatt über.
Dort möchte ich zwei Anmerkungen machen.
Einerseits zum Thema Hash-Funktion für die Aufgabe 1.4 und
andererseits zur Sichtbarkeit von Variablen.
Zur Hash-Funktion vielleicht ein Punkt.
Da waren im Forum ein paar Fragen aufgekommen, ob diese Funktion nicht
ein bisschen ungeschickt gewählt ist oder ähnliches.
Und ja, ich meine, wenn man sich die Aufgabe durchliest, steht ein
bisschen weiter unten, welche Nachteile hat diese Funktion.
Ich meine, wenn sie perfekt wäre, dann wäre diese Frage relativ
sinnfrei.
Das heißt also, Sie sollten da die Probleme identifizieren oder im
Prinzip sagen, was man an der Funktion noch besser machen könnte, um
sie zu beurteilen.
Was ist eigentlich eine Hash-Funktion?
Eine Hash-Funktion dient eigentlich primär dazu, eine lange Eingabe,
zum Beispiel einen Text, auf eine kurze Ausgabe, zum Beispiel eine
Zahl, abzubilden.
Die kurze Ausgabe wird auch als Hash-Wert bezeichnet.
Wozu braucht man das?
Es gibt verschiedenste Anwendungsfälle, wo wir Hash-Werte brauchen.
Ein Punkt ist zum Beispiel, wenn wir zwei Dokumente vergleichen
wollen.
Wir haben zwei Dokumente und wir wollen überprüfen, ob diese beiden
identisch sind.
Typischer Anwendungsfall, Sie laden im Internet eine Datei runter und
wollen wissen, ob das die Datei war, die auf dem Server sich befunden
hat.
Jetzt können Sie die Datei zweimal runterladen und dann vergleichen.
Oder Sie laden die Datei runter, bilden einen Hash-Wert und der, der
die Datei hochgeladen hat, hat auch den Hash-Wert dort abgelegt und
können dann die beiden Hash-Werte vergleichen.
Dann brauchen Sie nur noch den Hash-Wert runterladen.
Analog ist es eben, kann man das natürlich auch auf einem lokalen
Rechner machen, wenn man sagt, ich möchte nicht das ganze Dokument
vergleichen, das ist mir viel zu viel Arbeit.
Ich vergleiche bloß diesen kleinen Hash-Wert und wenn der
übereinstimmt, oder wenn der nicht übereinstimmt, dann kann ich sicher
sagen, dass die Dokumente nicht gleich sind.
Wenn er übereinstimmt, kann ich nicht hundertprozentig sagen, dass er
übereinstimmt, weil ein Hash-Wert dadurch, dass er kürzer ist,
natürlich weniger Informationen trägt als das Ausgangsdokument und
dementsprechend kann es passieren, dass zwei Dokumente, obwohl sie
nicht identisch sind, auf den gleichen Hash-Wert abgebildet werden.
Das Ganze wird als Kollision bezeichnet.
Wir können zum Beispiel auch hier eine einfache Hash-Funktion nehmen.
Wir haben eine ganze Zahl als Eingabe und der Hash-Wert ist die letzte
Ziffer.
Das wäre eine einfache Hash-Funktion.
Können Sie sich vorstellen, welche Vorteile und Nachteile diese Hash
-Funktion hat?
Fangen wir mal mit den Nachteilen an.
Naja, das Problem ist, wenn ich Zahlen habe, sagen wir mal, ich mache
da 15 Zahlen rein, dann habe ich zumindest fünf Kollisionen.
Das heißt, die Kollisionshäufigkeit ist bei dieser Funktion relativ
hoch.
Das heißt, auch die Wahrscheinlichkeit, wenn ich zwei beliebige Zahlen
nehme, ist relativ hoch, dass ich eine Kollision erzeuge.
Sie hat aber auch Vorteile.
Ein ganz gravierender Vorteil ist, sie kann ganz einfach berechnet
werden.
Das ist auch häufig bei den Hash-Funktionen.
Die sollen nicht nur die Sache verkürzen, sondern sie sollen häufig
auch dazu eingesetzt werden, um Effizienz zu gewinnen.
Das heißt, eine Hash-Funktion, die sehr aufwendig zu berechnen ist,
ist in der Hinsicht dann natürlich auch nicht gut geeignet.
Das heißt also, Hash-Funktionen sollten normalerweise sehr einfach
berechenbar sein.
Das ist also auch ein wesentliches Kriterium.
Das ist hier erfüllt, allerdings auf Kosten der hohen
Kollisionshäufigkeit.
Gut, kommen wir noch zur Sichtbarkeit von Variablen.
Welcher Unterschied...
Was ist der Unterschied zwischen den beiden Variablen-Deklarationen?
Wir haben einmal die Variable i als public deklariert und einmal als
private.
Das ist in der Vorlesung auch schon kurz angesprochen worden.
Der Unterschied ist, dass nicht alle...
Es ist die Menge der Methoden, die darauf zugreifen können.
Solange die Methode public ist, kann man von überall, von jeder
anderen Klasse aus, auf diese Variable zugreifen.
Sofern sie private ist, kann nur die Klasse selbst darauf zugreifen.
Und das ist eigentlich schon die...
Das heißt, hier haben wir eigentlich public, alle können zugreifen.
Und hier nur die Klasse.
Beziehungsweise die Methoden der Klasse können darauf zugreifen.
Hier habe ich gesagt, alle können darauf zugreifen.
Unter welchen Bedingungen kann man nicht auf eine Variable zugreifen,
die public deklariert ist.
Ja gut, das ist schon relativ spezifisch.
Das ist, wenn sie durch eine lokale Variable des gleichen Namens
überdeckt wird.
Aber grundsätzlich ist es eben so, sobald es public ist, kann jeder
darauf zugreifen.
Das sollte man so weit wie möglich vermeiden.
Lesen Sie in jedem Java-Programmierbuch.
Sie sollten vermeiden, dass Attribute public nach draußen gegeben
werden.
Aber was mache ich denn dann, wenn ich jetzt auf diese Attribute
zugreifen möchte?
Wenn ich sie ändern möchte, wenn ich sie lesen möchte?
Ich verwende sogenannte Get-und-Set-Methoden, die im Endeffekt nur
nach draußen die Inhalte dieser Variable geben.
Damit ist allerdings dann auch festgelegt, dass nur über diese
Methoden die Variablen auch verändert werden können.
Und das ist eigentlich der Sinn der Sache.
Das heißt, wir verwenden hier so Get-Set-Methoden.
Die dann natürlich public sein müssen, damit ich auch von außen darauf
zugreifen kann.
So, gut, das war's von meiner Seite für heute.
Ich hätte noch eine kleine Sache, was ich Sie bitten würde, wenn Sie
noch Fragen haben, wenn irgendwas noch unklar geblieben ist.
Ich meine, wir gehen jetzt langsam auf die Klausur zu.
Kommen Sie auf mich zu, entweder nach der Veranstaltung oder per E
-Mail.
Und geben Sie mir Bescheid, dann kann ich vielleicht noch was in die
nächsten Übungen mit einbauen, damit Sie ja gut vorbereitet in die
Klausur gehen können.
Gut, soviel für heute.
Tschüss!