Liste mit Stapeln von Kisten mit Pascal
-
Guten Morgen zusammen,
momentan hänge ich bei einer Übungsaufgabe und würde mich über Hilfe oder Anregungen sehr freuen. Es geht sich um folgendes Codefragment:
procedure remove(inName:String; var ioKiste:tRefKiste); {Entfernt die oberste Kiste eines Stapels} var pKiste : tRefKiste; gefunden : boolean; procedure abhaengen (var ioZeig : tRefKiste); var Hilfszeig : tRefKiste; begin {abhaengen} Hilfszeig := ioZeig; ioZeig := iozeig^.next; dispose (hilfszeig) end;{abhaengen} begin {remove} gefunden := false; if ioKiste = nil then {Liste ist Leer} gefunden := false; if ioKiste <> nil then {Liste ist nicht leer} if ioKiste^.name = inName then abhaengen(ioKiste) {erstes Element ist zu entfernen} else begin {durchlaufen der Liste} pKiste := ioKiste; while (pKiste^.next <> nil) and not (gefunden) do if pKiste^.next^.name = inName then abhaengen(pKiste^.next) else pKiste := pKiste^.next; end; {durchlaufen} end; {remove}
Und zwar muss die letzte Kiste eines gesuchten Stapels gefunden und abgehängt werden, und mit dieser Prozedur soll das Abhängen geschrieben werden.
Die ioKisten sind folgendermaßen aufgebaut:
es existieren 4 Zeiger in jeder Kiste und zwar mit:
- Up (für die nächste obere Kiste),
- Zahl,
- Name,
- Next (für den nächsten Stapel)
Mit freundlichen Grüßen,
Denis
-
Und wie lautet deine Frage?
-
Eine richtige Frage ist es nicht unbedingt, nur habe ich das Gefühl mich irgendwo "verlaufen" zu haben oder den sprichwörtlichen Wald vor lauter Bäumen nicht mehr zu sehen.
Deshalb habe ich es hier mal rein gestellt, um Anregungen zu erhalten, wie man es anders/besser machen kann, da ich es ja auch besser verstehen und auch besser werden möchte
-
Gut, dann gebe ich mal meinen Senf dazu:
-
auch wenn man in Pascal Funktionen verschachteln kann, ist das häufig keine so gute Idee. Ich würde daher eher das "abhaengen" rausziehen. Dann entfällt auch der Kommentar für den Funktionsnamen bei begin/end.
-
was tut "abhängen" genau? Ist nicht das wesentliche an dieser Funktion, dass sie vorne abhängt? Wäre vielleicht gut, das im Namen zu haben.
-
in folgendem Code:
gefunden := false; if ioKiste = nil then {Liste ist Leer} gefunden := false;
Hier ist erstmal die Einrückung nicht gut (in Zeile 3 in meinem Zitat). Aber das andere ist: in Zeile 1 setzt du gefunden auf false. In der nächsten Zeile machst du irgendeinen if-Test und wenn der true ist, dann setzt du gefunden erneut auf false, weil du dem false-Setzen in Zeile 1 nicht vertraust? In anderen Worten: die Zeilen 2 und 3 sind überflüssig.
-
Dann sieht deine Funktion zum Entfernen sehr kompliziert aus - insbesondere sowas wie
if pKiste^.next^.name = inName then
- vielleicht wäre es klüger, immer nur den aktuellen Namen zu testen (alsopKiste^.name
) und wenn der nicht gefunden wird, auf next zu springen? -
Da du auch einen up-Pointer hast, musst du den auch anpassen.
-
Und dieser Text hier ist nicht korrekt:
es existieren 4 Zeiger in jeder Kiste und zwar mit:
- Up (für die nächste obere Kiste),
- Zahl,
- Name,
- Next (für den nächsten Stapel)
Es gibt nur 2 Zeiger, nicht 4, nämlich up und next. Zahl und Name sind keine Zeiger.
-
-
@AhornGrabung10 Eine Meldung an die aufrufende Procedire, ob die Aktion erfolgreich war, wäre auch ganz nützlich.
-
Erstmal vielen Dank für die Kommentare bis jetzt
Das Verschachteln von Funktionen finde ich auch nach einer Zeit sehr unübersichtlich, und werde versuchen dies einfacher zu gestallten.
Die Funktion abhängen sollte eigentlich, die oberste Kiste des Stapels löschen, habe aber eben selber erkannt, dass ich im Stapel gar nicht nach oben gehe werde also nachher mal schauen, wie ich den Up-Pointer da rein baue.
Was mich da mit dem If-Test geritten hat, könnte ich jetzt nicht mehr sagen.
Ich werde mich nochmal ran setzen und werde eure Vorschläge beherzigen
Vielen Dank schon einmal und ich wünsche euch einen schönen Abend noch
-
Guten Tag zusammen
ich habe mich nochmal ran gesetzt und versucht, die Punkte zu berücksichtigen. Habe nun aber das Gefühl es verschlimmbessert zu haben werde aber trotzdem weiter dran bleiben und es weiter versuchen. Habe zudem versucht mehr mit den Zeigern zu arbeiten, was sich aber als schwieriger herausstellt als gedacht.
Hat sich eurer Meinung nach etwas verbessert, oder befinde ich mich auf dem falschen Weg? Habe versucht mehr Fallunterscheidungen zu betrachten, was m.M.n. die Struktur verbessert
Viele Grüße,
Denis
procedure remove(inName:String; var ioKiste:tRefKiste); {entfernt das letzte Element eines gesuchten Stapels} var p1, p2 : tRefKiste; begin {procedure} p1 := nil; p2 := nil; if (ioKiste <> nil) then {prüft ob Kiste leer} begin if (inName = ioKiste^.name) then {prüft ob erster Stapel der richtige ist} begin if (ioKiste^.up = nil) then {keine weitere Kiste oben} begin p1 := ioKiste^.next; dispose(ioKiste); ioKiste := p1; end {if keine weitere Kiste oben} else begin {weitere Kisten oben} p1 := ioKiste; if (p1^.up <> nil) then {nach oben laufen} begin while (p1^.up <> nil) do begin p2 := p1; p1 := p1^.up; end; {while} end; {nach oben laufen} dispose(p1); p1 := ioKiste; p2 := ioKiste; end {else weitere Kisten oben} end {if Prüfung Stapel eins} else begin {prüft weitere Stapel} while (inName <> ioKiste^.name) AND (ioKiste^.next <> nil) do {nach rechts laufen bis Stapel gefunden} begin ioKiste := ioKiste^.next; end; {while} if (ioKiste^.up = nil) then {keine weitere Kiste oben} begin p1 := ioKiste^.next; dispose(ioKiste); ioKiste := p1; p2 := p1; end {if keine weitere Kiste oben} else begin {weitere Kisten oben} p1 := ioKiste; p2 := ioKiste; if (p1^.up <> nil) then {nach oben laufen} begin while (p1^.up <> nil) do begin p2 := p1; p1 := p1^.up; end; {while} end; {nach oben laufen} dispose(p1); p1 := ioKiste; p2 := ioKiste; end {else weitere Kisten oben} end {else Prüfung für weitere Stapel} end {if leere Kiste} end; {procedure}
-
Was ich bei dir generell noch nicht verstanden habe, ist, was eigentlich exakt die Aufgabe der Funktionen ist. Was bedeutet "entfernt das letzte Element eines gesuchten Stapels"? Wieso hat remove diesen
inName
-Parameter? Wenn remove das letzte Element entfernen soll, dann sollte es nur genau das tun. Was ist ein "Stapel"? Wenn ich das richtig verstehe, hast du doch eine verkettete Liste?Dann würde ich generell dazu raten, dass du zwei Dinge trennst:
- Die Node. Zum Beispiel so:
type PNode = ^TNode; TNode = record up: PNode; next: PNode; name: String; end;
Und dann separat dazu eine Klasse, die einen Head-Pointer hat und die Funktionen enthält:
type TLinkedList = class private head: PNode; public constructor create; // hier head auf nil initialisieren destructor destroy; // hier dann alle Nodes löschen procedure add_front(...); function pop_front: String; ... end;
(Keine Garantie für die Syntax, habe schon lange kein Delphi mehr geschrieben)