Pascal Übungsaufgabe zu Listen

LMBVIA

Newbie
Registriert
Jan. 2023
Beiträge
2
Ich bin den Code schon etliche Male durchgegangen, aber ich verstehe einfach nicht wie man auf die Musterlösung kommt.

Beim ersten Schleifendurchlauf ist mir noch alles klar. get(A,3) gibt [3,4,false] aus und fügt es in Liste B hinzu, aber warum liefert get(A,4) beim zweiten Schleifendurchlauf [4,10,false] und nicht [4,99,false] als Ergebnis zurück?

Die get Funktion beginnt doch immer wieder am Anfang von Liste A. Sprich bei get(A,4) sollte zunächst [8,99,false] überprüft werden, was false ausgibt da 4 <> 8, und danach wird [4,99,false] geprüft was meiner Meinung nach die Bedingungen erfüllt.

Somit wäre die Lösung der Aufgabe nach meiner Logik aber [3,4][4,99].

Ich hoffe, es kann mir jemand helfen. Ich weiß einfach nicht wo mein Denkfehler liegt.
Grüße

Gegeben sind die folgenden Typdefinitionen, zwei Funktionen und zwei Prozeduren.

type
tRefKante = ^tKante;
tKante = record
von: integer;
zu: integer;
x:boolean;
next: tRefKante
end;

procedure push(inVon:integer; inZu:integer; var ioG:tRefKante);
var
n:tRefKante;
begin
new(n);
n^.von := inVon;
n^.zu := inZu;
n^.x := false;
n^.next := ioG;
ioG := n
end;

function get(inG:tRefKante; inVon:integer):tRefKante;
var
n:tRefKante;
begin
get := nil;
n := inG;
while (n <> nil) do
begin
if ((n^.von = inVon) and (not n^.x)) then
get := n;
n := n^.next;
end;
end;

function wasPassiert(inG:tRefKante; inVon:integer; inZu:integer):tRefKante;
var
akt:integer;
kante:tRefKante;
B:tRefKante;
begin
akt := inVon;
B := nil;
while ((akt <> inZu) and (akt <> 0)) do
begin
kante := get(inG,akt);
if (kante <> nil) then
begin
push(kante^.von,kante^.zu,B);
akt := kante^.zu;
kante^.x := true
end
else
begin
if (B <> nil) then
B := B^.next;
if (B = nil) then
akt := 0
else
akt := B^.zu
end;
end;
wasPassiert := B
end;

procedure print(inGraph:tRefKante);
var
e,f : tRefKante;
begin
e := inGraph;
while (e^.next <> nil) do
begin
e := e^.next;
end;
write('[',e^.von, ',', e^.zu,']');
while (e <> inGraph) do
begin
f := inGraph;
while (f^.next <> e) do
begin
f := f^.next
end;
write('[',f^.von, ',', f^.zu,']');
e := f
end;
end;


Gegeben ist die folgende Liste A.

A -> [8,99,false] -> [4,99,false] -> [8,10,false] -> [10,8,false] -> [4,10,false] -> [4,3,false] -> [3,4,false] -> nil



Welche Rückgabe liefert der Aufruf print(wasPassiert(A,3,99))?
Die Musterlösung lautet:
Die Funktion sucht einen Weg von 3 nach 99. Die Ausgabe ist:

[3,4][4,10][10,8][8,99]
 
Uff. Also irgendwas stimmt da (hoffentlich) mit der Formatierung nicht. Zumindest die Einrückung fehlt. Es tut mir jedenfalls leid, dass du solchen code lesen musst. Programmieren lernen besteht eigentlich nicht darin, möglichst unleserlichen Code zu analysieren. Guter Code ist gut lesbar und jemand, der anderen Programmiern bei bringt, sollte guten Code vorsetzen und nicht sowas write('[',f^.von, ',', f^.zu,']'); e := f. Jemand, der anderen Pascal beibringt hat vermutlich selber seit 20 Jahren nichts neues mehr dazugelernt.
 
@LMBVIA Falls du Hilfestellung zu diesem Code möchtest so solltest du ihn bitte in einer vernünftigen Formatierung hier darstellen. Ansonsten ist es sehr schwer etwas zu erkennen.
An die Anderen: Es gibt auch noch moderne und konkurrenzfähige Pascal-Compiler und IDEs wie Free Pascal. Dass man nichts dazu gelernt hat wenn jemand "Pascal" schreibt ist eine sehr unqualifizerte Aussage.
 
  • Gefällt mir
Reaktionen: DoNG
@LMBVIA

Habe mal tief im Gedächtnis gekramt und nachdem ich auf keine andere Lösung kam, habe ich es mal in einen Compiler geworfen.

https://onlinegdb.com/M5xn1NKN-

Output: [3,4][4,99]
 
Vielen Dank für eure Antworten und entschuldigt den schlecht formatierten Code.

Code:
type   
tRefKante = ^tKante;
tKante = record
           von: integer;
           zu: integer;
           x:boolean;
           next: tRefKante
         end;

procedure push(inVon:integer; inZu:integer; var ioG:tRefKante);
  var
  n:tRefKante;
begin
  new(n);
  n^.von := inVon;
  n^.zu := inZu;
  n^.x := false; 
  n^.next := ioG;
  ioG := n
end;

function get(inG:tRefKante; inVon:integer):tRefKante;
  var
  n:tRefKante;
begin
  get := nil;
  n := inG;
  while (n <> nil) do
  begin
    if ((n^.von = inVon) and (not n^.x)) then
      get := n;
    n := n^.next;
  end;
end;
 
function wasPassiert(inG:tRefKante; inVon:integer; inZu:integer):tRefKante;
  var
  akt:integer;
  kante:tRefKante;
  B:tRefKante;
begin
  akt := inVon;
  B := nil;
  while ((akt <> inZu) and (akt <> 0)) do
  begin
    kante := get(inG,akt);
    if (kante <> nil) then
    begin
      push(kante^.von,kante^.zu,B);
      akt := kante^.zu;
      kante^.x := true
    end
    else
    begin
      if (B <> nil) then
        B := B^.next;
      if (B = nil) then
        akt := 0
      else
        akt := B^.zu
    end;
  end;
  wasPassiert := B
end;

procedure print(inGraph:tRefKante);
  var
  e,f : tRefKante;
begin
  e := inGraph;
  while (e^.next <> nil) do
  begin
    e := e^.next;
  end;
  write('[',e^.von, ',', e^.zu,']');
  while (e <> inGraph) do
  begin
    f := inGraph;
    while (f^.next <> e) do
    begin
      f := f^.next
    end;     
    write('[',f^.von, ',', f^.zu,']');
    e := f
  end;
end;
 
Gegeben ist die folgende Liste A. 
A -> [8,99,false] -> [4,99,false] -> [8,10,false] -> [10,8,false] -> [4,10,false] -> [4,3,false] -> [3,4,false] -> nil
 
Welche Rückgabe liefert der Aufruf print(wasPassiert(A,3,99))?
 
Auf den ersten Blick sieht der Code abenteuerlich aus. Warum der Prof Listen so einführt als linked list weiß er wohl nur selbst.

@TorenAltair Wie hast du das compilliert? Das man funktionsname := equivalent zu result := verwenden kann wäre mir neu.
 
@Michael-Menten einfach den Link anklicken..das ist ein (Pascal)-Online-Compiler
 
Außerdem hat das Programm ein Speicherleck.
Wenn man New() macht, muss man auch Dispose() machen.
Im Demo mag das nicht auffallen, da das System den Speicher nach Programmende freigibt, aber wenn man die Routinen so unverändert irgendwo einsetzen würde, wo die Applikation länger läuft, würde es irgendwann wegen Speichermangel abstürzen.
 
  • Gefällt mir
Reaktionen: TorenAltair
Gliese schrieb:
Außerdem hat das Programm ein Speicherleck.
Wenn man New() macht, muss man auch Dispose() machen.
Ich hatte in der abgetippten Version irgendwann sogar ein dispose hinzugefügt, aber wohl irgendwann wieder gelöscht.
 
Zurück
Oben