WS07/08 aufgabe 3

K.I.T.T.
Neuling
Neuling
Beiträge: 7
Registriert: 30. Aug 2008 16:36

WS07/08 aufgabe 3

Beitrag von K.I.T.T. »

ich habe ziemlich probleme bei den konstruktoren für die Aufgabe 3, also bei der a und der b. kann mir jemand einen tipp geben, wie ich vorgehen muss?


die a) habe ich wie folgt gemacht

Code: Alles auswählen

public NNList(int z){
     this.z = z;
     n1 = null;
     n2 = null;
}
bei der b) bekommt man aber ein array von zahlen. ich weiß nicht, wie man dafür die elemente initialisiert, auf die gezeigt wird.

mein ansatz hierfür war:

Code: Alles auswählen

public NNList(int[] z){
   int L = z.length;
   NNList list = new NNList(z[0])
   for(k=1, k<L, k++){
        list.n1 = new NNList(z[k]);
        list = list.n1;
}
}


werden dabei nicht die elemente überschrieben? ist das vom prinzip her richtig oder falsch? ich denke es geht so nicht... wenn ich nun für die übernächsten elemente durchgehen will, muss ich mit meiner liste wieder zurückspringen. das könnte man ja z.b. ganz am anfang mit
NNList X = list;
machen und dann nochmals die schleife über X.n1 laufen lassen. dann hätte man aber wohl eine andere art von liste weil wenn man zu einer instanz sagt liste.n1.n1.n2, dann wäre es null


wäre dankbar für einen Hinweis, komm nicht wirklich weiter hier.

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Hallo!

Deine a) ist richtig.

Auch der Ansatz für die b) ist soweit in Ordnung, du hast da nur einen Haufen Syntax-Fehler drin (guck dir mal meine version weiter unten an). Außerdem vergisst du, die Liste mit deinem ersten Element zu verketten. Nein, überschrieben wird da nichts, weil du ja list immer auf das jeweils neuste Objekt setzt:

Code: Alles auswählen

list = list.n1
Ein kompletter Ansatz könnte bspw. so aussehen:

Code: Alles auswählen

public NNList(int[] z){
   this(z[0]);
   NNList list = this;
   for(int k=1; k<z.length; k++){
        list.n1 = new NNList(z[k]);
        list = list.n1;
   }
   // Die n2-Verweise
   list = this; // Wieder vorne anfangen
   for (int k=1; k<(z.length - 1); k++) {
        list.n2 = list.n1.n1;
        list = list.n1;
   }
}
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

K.I.T.T.
Neuling
Neuling
Beiträge: 7
Registriert: 30. Aug 2008 16:36

Re:

Beitrag von K.I.T.T. »

ich kenne die ausdrücke von "this" nicht. kam das in der vorlesung/übung überhaupt? also z.B.

Code: Alles auswählen

this(z[0]);
NNList list = this;
ist mir unbekannt.

was macht das? kann man nicht auch

Code: Alles auswählen

NNList list = new NNList(z[0])
schreiben stattdessen? was gibt es noch für möglichkeiten zurückzuspringen?

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

this ist ein Zeiger auf das aktuelle Objekt, ich nutze this(int i) um auf den anderen Konstruktor der Klasse zuzugreifen (siehe Folie 8.32). Wenn eine neue NNList erzeugt wird, egal ob mit einem Array als Parameter im Konstruktor oder nur einem integer, wird ja eine Instanz von NNList zurückgegeben. Bspw. könntest du in deinem "echten" Programm später irgendwo eine neue NNList erzeugen, indem du

Code: Alles auswählen

NNList meineListe = new NNList(meinArray);
schreibst. Dann soll meineListe.n1 dir Zugriff auf das zweite Objekt in deiner Liste geben.

Wenn du jetzt allerdings in deinem Konstruktor nur

Code: Alles auswählen

NNList list = new NNList(z[0]);
schreibst, verknüpfst du das neu erzeugte Element nicht mit meineListe, in deinem Hauptprogramm kannst du jetzt also nicht auf meineListe.n1 zugreifen (bzw. es ist null), da die echte Liste zwar komplett im Speicher liegt, aber aus meineListe nicht erreicht werden kann.
Das Ganze mit this() ist im Endeffekt die Kurzschreibweise für

Code: Alles auswählen

public NNList(int[] z){
   this.z = z[0];
   this.n1 = null;
   this.n2 = null;
   NNList list = this;
   ...
}
, es wird also nur der alte Konstruktor verwendet (wie in der Aufgabenstellung gewünscht).

Die Zeile

Code: Alles auswählen

NNList list = this;
sorgt dafür, dass in list der Verweis auf mein meineListe Element, also den ersten Teil der Liste, steckt. Ich kann also jetzt mein z für das erste Element über this.z oder über list.z ändern - mehr nicht. Das ist auch nur nötig, damit ich in der Schleife danach list auf das jeweils nächste Element setzen kann.
Daran siehst du jetzt auch, dass der Rest der Liste tatsächlich mit meinem ersten Element (meineListe) verknüpft ist: im ersten Schleifendurchlauf setze ich list.n1 auf das neu erzeugte Objekt - und das würde in dem Fall nichts anderes bedeuten, als this.n1 auf das neue Objekt zu setzen.

Zurückspringen in dem Sinne kannst du gar nicht, da du die ganze Zeit noch im Konstruktor deines "ersten Elementes" steckst und quasi auf die this.n1.n1.n1.n1.n1.n1-Art immer neue Elemente anhängst. Über this hast du also jederzeit Zugriff auf dein erstes Element (das nutze ich ja auch in der Zeile vor der zweiten for-Schleife).

Ich hoffe das hat dir etwas weitergeholfen, wenn nicht einfach nochmal fragen!

Gruß,
Björn
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

K.I.T.T.
Neuling
Neuling
Beiträge: 7
Registriert: 30. Aug 2008 16:36

Re: WS07/08 aufgabe 3

Beitrag von K.I.T.T. »

vielen dank, ich denk ich hab es jetzt verstanden. this() ruft also den konstruktor auf und this verweist auf das aktuelle objekt.

als kleine this-übung hier mal die d)

Code: Alles auswählen

public int add_odd(){
     int sum = 0;
     while(this != null){
        sum += this.z;
        this = this.n2;
        }
     return sum;
     }

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Das solltest du so nicht machen, weil du dann this überschreibst, sprich das aktuelle Objekt gegen die Schleifenobjekte austauschst. Guck dir mal deine Liste in BlueJ nach dem Ausführen von add_odd an, du wirst sehen, dass sich das erste Element ändert.
Um dem zu entgehen, musst du nur eine Hilfsvariable für die for-Schleife einführen:

Code: Alles auswählen

public int add_odd(){
     int sum = 0;
     NNList current = this;
     while(current != null){
        sum += current.z;
        current = current.n2;
        }
     return sum;
}
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

sheme
Neuling
Neuling
Beiträge: 7
Registriert: 24. Mai 2008 15:39

Re: WS07/08 aufgabe 3

Beitrag von sheme »

Hallo,
hab ne Frage zur d)

in der aufgabenstellung steht "beginnend mit dem momentanen ersten Listenelement" :shock: danach ist nach meiner Auffassung das überhaupt erste Element gemeint.
Wie greife ich denn darauf zu ohen in einem vorigen Aufgabenteil ein firstElement oder sowas zu definieren.
Wenn ich this benutze würde es ja nur funktionieren, wenn ich auch das erste Element als das Methoden ausführende Objekt benutze! :shock:

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Hi!
Also das momentan erste Element ist hier sicherlich das aktuelle Element, auf dem die Methode aufgerufen wird. Aus Sicht des Elementes ist es schließlich immer das erste, es weiß ja nur über seine Nachfolger Bescheid und mehr nicht.
Ansonsten hast du Recht, du müsstest dann den Startpunkt irgendwo speichern.

Gruß,
Björn
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

K.I.T.T.
Neuling
Neuling
Beiträge: 7
Registriert: 30. Aug 2008 16:36

Re: WS07/08 aufgabe 3

Beitrag von K.I.T.T. »

Bjoern hat geschrieben:Das solltest du so nicht machen, weil du dann this überschreibst...

okay, aber das ergebnis stimmt trotzdem. nur wenn ich die methode dann an einer konkreten NNListe verwende, besteht sie am end nur noch aus einem element. oder?

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Ne, also eigentlich müsstest du dann einen Fehler beim Kompilieren bekommen...

Code: Alles auswählen

this = irgendwas; 
ist immer böse.
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

zwieback-dude
Neuling
Neuling
Beiträge: 10
Registriert: 28. Aug 2008 23:47

Re: WS07/08 aufgabe 3

Beitrag von zwieback-dude »

Hi,

hab auch ne Frage zur Aufgabe 3b). Kann ich für den 2. Konstruktor anstatt der 2. forschleife für die n2-Verweise auch eine while schleife nutzen?

Code: Alles auswählen

while(current.n1.n1 != null) {
   current.n2 = current.n1.n1;
   current = current.n1;
}

K.I.T.T.
Neuling
Neuling
Beiträge: 7
Registriert: 30. Aug 2008 16:36

Re: WS07/08 aufgabe 3

Beitrag von K.I.T.T. »

nagut, dann mach ich halt nur noch irgendwas = this

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Ja, ich würde deine Lösung eigentlich auch bevorzugen ^^
Da ist die Abbruchbedingung klarer.
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

frankmertins
Neuling
Neuling
Beiträge: 8
Registriert: 9. Apr 2008 19:34

Re: WS07/08 aufgabe 3

Beitrag von frankmertins »

Hier mal ein Versuch zur c.)

Wäre für Hilfe dankbar

Generell erstma, wenn nix verlangt ist schreibe ich nix vor Methoden oder Attribute und wenn ich nix schreibe wird es so behandelt wie public, oder?

void insert (int i){

NNList current = this.n2; //aktuelles Elemnt ist das übernächste, weil ich hier einfügen will
current = thi.n1; // das übernächste wird um 1 verschoben
NNList.current = new NNList (i); // neues Element wird an aktuelle Position eingefügt
}

Benutzeravatar
Bjoern
Mausschubser
Mausschubser
Beiträge: 53
Registriert: 1. Nov 2007 08:39
Wohnort: Darmstadt
Kontaktdaten:

Re: WS07/08 aufgabe 3

Beitrag von Bjoern »

Erst mal zu den Sichtbarkeiten:
Wenn du nichts davor schreibst, ist das ganze eine Mischung aus private und protected, jedenfalls nicht das von dir beabsichtigte public (Skript 12.42). Wenn nichts spezielles verlangt ist, würde ich die Methoden immer public machen.

Jetzt zu deiner c: Wenn du die die Schemazeichnung daneben anguckst, sind es genau 5 Verknüpfungen (Pfeile) die sich geändert haben. Du kannst also davon ausgehen, dass du alle 5 abarbeiten musst. Ich gehe da so ran, dass ich alle Verknüpfungen nach und nach durchgehe, dabei muss man nur aufpassen, dass man immer noch eine Verkettung und somit jederzeit Zugriff auf alle Elemente hat. Die Reihenfolge ist also entscheidend.

Code: Alles auswählen

void insert (int i){
    this.n2 = new NNList(i); // this.n2 auf das neue Element setzen, gestrichelter Pfeil links oben erledigt
    this.n2.n1 = this.n1.n1; // n1 des neuen Elementes setzen, Pfeil nach unten rechts erledigt
    this.n2.n2 = this.n1.n1.n1; // n2 des neuen Elements, gestrichelter Pfeil rechts oben erledigt
    this.n1.n2 = this.n2.n1; // n2 des zweiten Elementes setzen, gestrichelter Pfeil unten erledigt
    this.n1.n1 = this.n2; // Verweis vom zweiten auf das neue Element, Pfeil nach oben rechts erledigt
}
Natürlich kannst du auch neue Variablen einführen, um das Ganze etwas übersichtlicher zu gestalten, du musst aber in jedem Fall diese 5 Verknüpfungen ändern.
Und mit den Worten "Learning by doing" packte der ETler in die Steckdose.

Antworten

Zurück zu „Archiv“