umkehren der Liste in Lisp
Ich versuche, reverse eine Liste in Lisp, aber ich bekomme die Fehlermeldung: "Fehler: Ausnahme C0000005 [flags 0] 20303FF3
{Offset 25 in #}
eax 108 ebx 200925CA ecx 200 edx 2EFDD4D
esp 2EFDCC8 ebp 2EFDCE0 esi 628 edi 628 "
Mein code ist wie folgt:
(defun rev (l)
(cond
((null l) '())
(T (append (rev (cdr l)) (list (car l))))))
Kann mir jemand sagen was ich falsch mache? Vielen Dank im Voraus!
Ich verwende es als "sonst" - Zweig, nach, dass alle Voraussetzungen geprüft wurden..
Die Funktion für Common Lisp ist richtig. Die lisp verwenden Sie? elisp?
LispWorks Personal Edition 6.1.1
Funktioniert gut für mich (LW PE 6.1.1 auf dem Mac). Wie nennst du
Nur, wenn das erste element ist ein (sub-)Liste.
Die Funktion für Common Lisp ist richtig. Die lisp verwenden Sie? elisp?
LispWorks Personal Edition 6.1.1
Funktioniert gut für mich (LW PE 6.1.1 auf dem Mac). Wie nennst du
rev
?Nur, wenn das erste element ist ein (sub-)Liste.
InformationsquelleAutor Nelly | 2015-12-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihren code so geschrieben ist, ist logisch richtig und erzeugt das Ergebnis, das Sie wollen, es zu:
Sagte, es gibt einige Probleme mit ihm in Bezug auf Leistung. Die Anhängen - Funktion erzeugt eine Kopie von allen, aber seine endgültige argument. E. g., wenn Sie das tun (append '(1 2) '(a b) '(3 4)), erstellen Sie vier neue cons-Zellen, deren Wagen 1, 2, a, und b. Die cdr der Letzte der vorhandenen Liste (3 4). Das ist, weil die Umsetzung der Anhängen ist so etwas wie dieses:
Das ist nicht gerade Common Lisp ist Anhängen, da Common Lisp ist Anhängen können mehr als zwei Argumente. Es ist nahe genug, um zu demonstrieren, warum alle, aber die Letzte Liste kopiert, obwohl. Schauen Sie sich jetzt was das bedeutet in Bezug auf Ihre Umsetzung rev, aber:
Dies bedeutet, dass, wenn man die Umkehrung einer Liste wie (1 2 3 4), es ist wie du bist:
Nun, in Zeile (2), Sie kopieren die Liste (4 3). In Zeile eins, Sie sind das kopieren der Liste (4 3 2), die eine Kopie von (4 3). Das ist, Sie sind kopieren eine Kopie. Das ist eine ziemlich verschwenderisch mit Speicher.
Eine weitere gemeinsame Ansatz verwendet eine Akkumulator-variable und eine Hilfsfunktion. (Beachten Sie, dass ich endp, rest, ersten, und Liste* statt null, cdr, Auto, und Nachteile, denn es macht es deutlicher, dass wir die Arbeit mit Listen, nicht willkürlich Nachteile-Bäume. Sie sind so ziemlich das gleiche (aber es gibt ein paar Unterschiede).)
Mit dieser Hilfsfunktion ist es einfach zu definieren, rev:
Sagte, dass, anstatt eine externe helper-Funktion, wäre es wahrscheinlich häufiger zu verwenden Etiketten so definieren Sie eine lokale Hilfsfunktion:
Oder, da Common Lisp ist nicht garantiert Optimierung Schwanz Anrufe, eine tun loop ist schön und sauber, auch hier:
Ich habe noch eine Frage.. was ist, wenn es sub-Listen in der ersten Liste? Ich habe versucht zu wenig modifizieren Sie den code mit "mapcar" - Funktion in "rev", aber ich bekomme das Ergebnis "gleich NULL" ... können Sie mir einen Vorschlag?
Ich bin mir nicht sicher, was du meinst, und sicherlich nicht erraten können, welches problem Sie lief in nur durch "ich bekomme das Ergebnis gleich NULL". Sie brauchen keine änderung für Listen, die Listen als Elemente. Wenn Sie reverse ((1 2) (3 4)) Sie bekommen ((3 4) (1 2)), eine neue Liste mit denselben Elementen, aber in umgekehrter Reihenfolge.
Ich bekam Ihren Punkt, und du hast Recht. Aber, ich möchte auch Umgekehrt Elemente aus dem sub-Listen. Also, das ist, warum ich schrieb so etwas wie: "( mapcar #'rev-Helfer-Liste '()) " in der "rev", und für die Instanz, Berufung " (rev '(1 2 '(3 4) 5 '(6 7))) "gibt mir das Ergebnis "gleich NULL" ..
Ich bin über Handy im moment, so kann ich keine vollständige Antwort. Erste, Sie werden nicht wollen, zu mehr quotes in das innere Listen. Das ist, tun '(1 2 (3 4)) nicht '(1 2 '(3 4)) [ich kann einen link zu einer anderen Frage über, die]. Zweitens, es gibt eine andere aktuelle Frage über die Umkehrung rekursiv, vermutlich tut Sie das, was Sie wollen. Dritte, die in Ihrem Versuch, Ihr mit mapcar falsch. Mapcar ruft die Funktion auf Argumente, die aus jeder Liste. E. g., (mapcar '+ (1 2) (3 4)) zurück (4 6), denn er fordert + mit 1 und 3, und dann mit 2 und 4. Wenn Sie tun, (mapcar #'rev-Helfer-Liste '()), die zweite
InformationsquelleAutor Joshua Taylor
In ANSI Common Lisp, können Sie umkehren einer Liste mit der
reverse
Funktion (zerstörungsfreie: reserviert eine neue Liste), odernreverse
(ordnet die Bausteine oder die Daten der bestehenden Liste zu produzieren, die Umgekehrt).Nicht verwenden
nreverse
auf die zitierte Liste Literale; es ist Undefiniertes Verhalten und Verhalten können in erstaunlicher Weise, da es de facto self-modifying code.InformationsquelleAutor Kaz
Wenn Sie können, verwenden Sie die standard-CL-Bibliothek Funktionen wie
append
, sollten Siereverse
(wie Kaz vorgeschlagen).Sonst, wenn dies ist eine übung (h/w oder nicht), können Sie versuchen, diese:
PS. Ihre spezifischen Fehler nicht nachvollziehbar ist, Kontaktieren Sie bitte Ihren Händler.
InformationsquelleAutor sds
Haben Sie wahrscheinlich laufen out of stack space; dies ist die Folge der Aufruf einer rekursiven Funktion,
rev
außerhalb der Schwanz-position. Der Ansatz für die Umwandlung in eine tail-rekursive Funktion ist die Einführung von einem Akku, der variableresult
im folgenden:Du
rev
Funktion wird dann:Beispiele:
consp
ist die Art Prädikat für eine "cons-Zelle". Jeder richtige Liste ist eine Sequenz von cons-Zellen endet in einemnil
. Wenn Sie versuchen(cons 1 (cons 2 nil))
Sie erhalten eine Liste der(1 2)
. In meinemreving
code von oben, wennlist
ist eincons
dann drücken Sie diecar
aufresult
und recurse auf den rest der Liste (übercdr
).InformationsquelleAutor GoZoner