![]() |
result nicht gesetzt (rekursive Tiefensuche)
Ich habe hier einen funktionierenden ALgorithmus der Tiefensuche. Er arbeitet rekursiv und durchläuft einen Graphen (mit den selbsterklärenden Methodennamen - hoffe ich). Der Algorithmus findet nicht die optimale Lösung (Weg von Knoten start zu Knoten ziel) aber er findet zumindest eine Lösung.
Meine Frage lautet eher: Warum funktioniert das Ganze?
Delphi-Quellcode:
Genauer gesagt: Was genau hat eine Methode für einen Wert, wenn result nicht gesetzt wird? Warum wird result (wenn einmal eine Lösung gefunden wurde) nicht immer wieder mit NIL oÄ überschrieben?
//-------- tiefensuche (public) ----------------------------------------
function TGraphAlgorithms.tiefensuche (graph: TGraph; start: TGraphNode; ziel: TGraphNode; weg: String) : String; var l : TList; begin start.mark; if start.getName = ziel.getName then result := weg else begin l := graph.getNeighbours(start); l.toFirst; while l.hasAccess do begin if NOT (l.getObject as TGraphNode).isMarked then result := tiefensuche(graph, (l.getObject as TGraphNode), ziel, weg + (l.getObject as TGraphNode).getName); l.next; end; end; end; |
AW: result nicht gesetzt (rekursive Tiefensuche)
Zitat:
Delphi-Quellcode:
, jedenfalls dann, wenn man nicht explizit einen anderen Wert zuweist.
''
Zitat:
Vermutlich hab ich das jetzt nicht besonders gut und evtl. sogar falsch erklärt :D. MfG Dalai |
AW: result nicht gesetzt (rekursive Tiefensuche)
Du hast da einen "zufällig" funktionierenden Code.
Wenn man diese Funktion mehrfach in einer Schleife aufruft, dann wirst du dich womöglich wundern, daß es nicht immer funktioniert. :angle2: Deswegen warnt dich ja auch der Compiler davor. Geh doch mal deinen Code durch und schau, ob dem Result wirklich immer etwas zugewiesen wird. Tipp: Was passiert wohl, wenn in der Schleife das IF niemals zutrifft? |
AW: result nicht gesetzt (rekursive Tiefensuche)
Hallo und Danke für die Antwort, aber das genau ist mein Problem:
zum ersten Kommentar: ich verstehe schon, warum der Algorithmus funktioniert, wenn etwas sinnvolles gefunden wird. Das Prinzip der Rekursion ist mir schon klar. Schließlich stammt der Code ja auch von mir ;-) Der Code funktioniert tatsächlich aber auch, wenn die erste if-Abfrage nicht zutrifft. Dann wird halt ein leerer String zurückgegeben. Das ist aber das Problem. Wenn nämlich eine Funktion, deren result-Wert nicht belegt wird zu einem leeren String '' ausgewertet wird, dann müsste doch eine einmal gefundene Lösung letztendlich überschrieben werden, wenn weitere Nachfolger gefunden werden, oder? Konkret folgender Graph: A - B | C Gesucht ist der Weg von A nach B. Nun werden ja REKURSIV alle noch unbesuchten Nachfolger von A untersucht. Zuerst wird A B untersucht, Lösung "AB" wird als String an result zugewiesen. Nun wird aber noch AC überprüft, es wird keine Lösung gefunden, result wird also NICHT belegt und nun wird in der aufrufenden Methode, in welcher result ja noch der Wert "AB" hat dieser Wert mit NICHTS bzw. '' oder auch NIL überschrieben. Insgesamt müsste dann die Methode doch auch NIL oder '' ausgeben, oder? Tut sie aber nicht, denn sie liefert korrekterweise "AB" zurück. Ich hoffe, das war soweit verständlich ausgedrückt. |
AW: result nicht gesetzt (rekursive Tiefensuche)
Zitat:
Du mußt grundsätzlich davon ausgehen, daß ein Result niemals initialisiert ist. Bei Strings, Interfaces und dynamischen Arrays ist meisten zufällig ein '' zugewiesen, da diese Typen eine automatische Speicherverwaltung besitzen und demnach automatisch vom Delphi initialisiert werden. Allerdings werden diese Results (String, Interface und dyn. Array) intern nicht als Result-Parameter behandelt, sondern werden als VAR-Parameter. Die Initialisierung deines Strings befindet sich außerdem nicht in deiner Funktion, sondern beim Aufrufer, bzw. da, woran das Result zugewiesen wird, was eben bei mehrfachen Aufrufen, z.B. in einer Schleife zu Problemen führt, da diese Stringvariable nur einmal zu Beginn initialisiert wird und nicht bei jedem Aufruf. Hier würdest du doch bestimmt
Delphi-Quellcode:
in der MessageBox erwarten?
x
Ich allerdings nicht.
Delphi-Quellcode:
function Test: string;
begin Result := Result + 'x'; end; procedure TForm1.FormCreate(Sender: TObject); var i: Integer; S: string; begin for i := 1 to 10 do S := Test; ShowMessage(S); end; |
AW: result nicht gesetzt (rekursive Tiefensuche)
Hallo,
ich befürchte, wir reden aneinander vorbei. Hier ein einfacheres Beispiel:
Delphi-Quellcode:
Ich verstehe nicht, warum beim Aufruf
function TGraphTool.test (s : integer): String;
begin if s > 5 then result := '6'; if s < 5 then begin result := test(6); result := test(5); end; end; showMessage(test(4)); tatsächlich '6' ausgegeben wird und nicht etwa '' oder NIL oder so. |
AW: result nicht gesetzt (rekursive Tiefensuche)
Finde ich nicht, denn du hörst nicht zu.
Hier sollte ebenfalls wieder mindestens 1 Compilerwarnung auftauchen. - Rückgabewert nicht initialisiert (bei s = 5) - zugewiesener Wert wird nicht benutzt (das erste result := ..., im s < 5) Und genau deswegen kommt hier 6 raus, weil DU nichts initialisierst, denn sonst würde ein Leerstring aus deiner Funktion rauskommen. Es wird Test mit 4 Aufgerufen, also landet die Ausführung im S < 5. Dadurch wird dann erstmal Test mit 6 aufgerufen, was über S > 5 eine "6" liefert, danach dann nochmal Test mit 5, was "nichts" zurückliefert, aber da DU schonwieder vergessen hast das Result zu initialisieren und Aufgrund der von mir vorhin beschiebenen Eigenschaft von aufeinanderfolgenden Aufrufen, und Zuweisung auf die selbe Variable, wird die vorher gesetzte "6" nicht mit einem neuen Result "überschrieben". Außerdem empfehle ich dir dringend die Benutzung des Debuggers. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz