Wie zu erkennen, eine unendliche Schleife in einen rekursiven Aufruf?
Ich habe eine Funktion, die rekursiv sich selbst aufrufenden, und ich möchte zu erkennen und zu kündigen, wenn geht in eine Endlosschleife, ich.e - erste genannt, das gleiche problem wieder. Was ist der einfachste Weg, das zu tun?
EDIT: Das ist die Funktion, und Sie wird rekursiv aufgerufen mit verschiedenen Werten von x und y. ich will kündigen, wenn ein rekursiver Aufruf, der Wert des Paares (x,y) wiederholt.
int fromPos(int [] arr, int x, int y)
InformationsquelleAutor Pranav | 2009-06-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die Funktion ist rein funktional, d.h. es hat keine staatlichen oder Nebenwirkungen, dann könnten Sie halten eine
Set
der Argumente (edit: zu sehen, Ihre zu Bearbeiten, würden Sie halten eine Menge von Paaren (x,y) ) , es ist genannt worden, und jedes mal nur überprüfen, wenn das aktuelle argument ist in dem set. Auf diese Weise können Sie erkennen, einen Zyklus, wenn Sie es ziemlich schnell. Aber wenn das argument der Raum ist groß und es dauert eine lange Zeit, um zu wiederholen, können Sie aus dem Speicher, bevor Sie erkennen einen Zyklus. Im Allgemeinen, natürlich, Sie können es nicht tun, denn dies ist das Halteproblem.Diese Methode wird nicht erkannt, ob es legal ist für die Funktion manchmal rufen die sich mit den gleichen Werten -- in der Erwägung, dass die Rekursionstiefe Methode kann für den Allgemeinen Fall.
Oh, und es erfordert den Aufwand der Bau der Satz und die Einträge darin.
Vergessen Sie nicht, deaktivieren Sie die Menge, wenn Sie fertig sind.
Ich sagte: "wenn die Funktion hat keine Staats-oder Nebenwirkungen" (sollte ich auch hinzufügen "und hängt nicht von irgendeiner äußeren Zustand"); in diesem Fall ist es nicht in Ordnung für eine Funktion ruft sich selbst mit den gleichen Werten
InformationsquelleAutor newacct
Eine Möglichkeit ist die übergabe einer
depth
variable von einem Anruf zum nächsten, erhöht es jedes mal, wenn Ihre Funktion sich selber aufruft. Überprüfen Sie, dassdepth
nicht größer als die bestimmte Schwelle. Beispiel:+1 Schlagen mich auch.
Ich würde es bevorzugen, wenn die Signatur der Methode bleibt gleich.
Nur benutzen Sie überladung, um eine rückwärts-kompatibel-Signatur.
In diesem Fall, Sie heimlich nennen, eine 2. Funktion mit der Tiefe argument. Siehe überarbeitete Antwort.
InformationsquelleAutor John Kugelman
Können, benötigen Sie ein work-around, weil, wie Sie gefragt haben ist, gibt es keine Allgemeine Lösung. Finden Sie die Halteproblem für mehr info.
InformationsquelleAutor JP Alioto
Eine einfache Möglichkeit wäre die Umsetzung eines der folgenden:
Pass den vorherigen Wert und den neuen Wert des rekursiven Aufrufs und machen Sie Ihren ersten Schritt wird überprüft, ob diese identisch sind - dies ist ggf. der rekursive Fall.
Übergeben Sie eine variable, um die Anzahl anzugeben, wie oft die Funktion aufgerufen wurde, und willkürlich begrenzen die Anzahl der Zeiten, die Sie aufgerufen werden kann.
InformationsquelleAutor Relster
Kann man nur erkennen das die meisten trivial diejenigen, die mithilfe von Programm-Analyse. Das beste, was Sie tun können, ist fügen Sie Wachen in Ihrer jeweiligen Lebenssituation und geben Sie eine Tiefe Ebene Kontext. Es ist fast unmöglich zu erkennen ist der Allgemeine Fall und unterscheiden legitime Verwendung von rekursiven algorithmen.
InformationsquelleAutor ojblass
Können Sie entweder überladen für eine einheitliche Signatur (dies ist die bessere Methode), oder Sie können eine statische variable:
John Kugelman Antwort mit überlastung besser ist, weil es thread-sicher, während statische Variablen nicht.
Billy3
InformationsquelleAutor Billy ONeal
Sieht aus wie Sie sein könnten, arbeiten an einem 2D-array. Wenn Sie haben ein bisschen Freizeit in die Werte der array, können Sie es verwenden, wie eine fahne. Überprüfen Sie es, und beenden die Rekursion, wenn das flag gesetzt wurde. Dann legen Sie es, bevor Sie fortfahren.
Wenn Sie nicht ein wenig zu schonen, in der Werte, können Sie immer machen es ein array von Objekten statt.
InformationsquelleAutor patros
Wenn Sie möchten, um Ihre Signatur der Methode, die Sie halten konnte ein paar Sätze aufnehmen, die alten Werte von x und y.
Du hast Recht. Bearbeiten
Würde downvoter Kommentar?
InformationsquelleAutor Tom
IMHO Nur Schleifen können in einer endlos-Schleife.
Wenn Ihre Methode hat zu viele Ebene der Rekursion die JVM wirft einen StackOverflowError. Sie abfangen können diese Fehler mit einem try/catch-block und tun, was Sie tun möchten, wenn diese Bedingung Eintritt.
InformationsquelleAutor Peter Lawrey
Einer rekursiven Funktion wird beendet, falls eine Bedingung erfüllt ist.
Beispiele:
0
oder ist1
In Ihrem Fall die Bedingung ist
([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])
0, 1, ...N
sind die Indizes der PaareSo benötigen Sie einen container(vector, list, map) zu speichern, alle bisherigen Paare und vergleichen Sie mit der aktuellen paar.
InformationsquelleAutor Th. Thielemann
Ersten Verwendung mvn findbugs:gui öffnen einer gui, die auf die Linie, wo dieser Fehler vorhanden ist.
Ich auch vor dem gleichen problem, und ich löste es durch hinzufügen einer boolean variable in der Schleife die überprüfung.
Code vor ->
Um dieses problem zu Lösen, habe ich nur noch eine boolean-variable und setzen Sie ihn auf false, wird der catch-block. Prüfen Sie es nach unten
Dies ist, wie ich dieses problem Gelöst.
Hoffe, das wird helfen. 🙂
InformationsquelleAutor AKASH DUBEY