Frage

Ich wollte durch dieser Tutorial zum Spaß, und bekam auf der allerletzte, was steckte er sagt: „Übung: geben Sie eine linear rekursive Implementierung der Vereinigung und Differenz.“ (Liste)

Union, kein Schweiß.

Unterschied, Schweiß.

Ein Versuch, sieht wie folgt aus. . .

(defun list-diff (L1 L2)
  (cond
    ((null L1) L2) 
    ((null (member (first L1) L2)) (cons (first L1) (list-diff (rest L1) L2)))
    (t (list-diff (rest L1) L2))
  )
)

Nun, das gibt alle Elemente, die in L1 sind, die nicht in L2 sind, aber es gibt nur alle L2 (offensichtlich). Und falls ich den L2 in Zeile 3 auf „Null“ zu ändern, dann gibt es nur alle L1, die nicht in L2 ist, aber keiner von L2.

Meine Versuche, bei Umgehungen sehen nicht rekursiv, und wenn sie sind, ich am Ende Stack-Überlauf bekommen (wie wenn ich versuche Aufruf (list-diff L2 L1) irgendwo).

Jede seiner anderen Übungen, wie list-Kreuzung, erfordern nur durch die Elemente von L1 ausgeführt wird. Hier möchte ich die entscheidenden Elemente von L2 schlagen, oder laufen (list-diff L2 L1) und dann Union die Ergebnisse von beiden, aber das ist nicht wirklich linear rekursiven mehr.

Die Gedanken?

(nicht Hausaufgaben, wirklich. Ich dachte nur, ich würde versuchen irgend LISP für Spaß zu sehen.)

EDIT: eine Funktion, die dies richtig funktioniert, auf der Grundlage der Antworten lautet:

(defun list-diff (L1 L2)
  (cond
    ((null L1) nil)
    ((null (member (first L1) L2)) (cons (first L1) (list-diff (rest L1) L2)))
    (t (list-diff (rest L1) L2))
  )
)
War es hilfreich?

Lösung

Differenz Betrieb L1 \ L2, da alle Elemente E so definiert ist, dass e ist in L1 aber e nicht in L2. So sieht es für mich wie Ihr zweiten Versuch ist eigentlich richtig:

  

Und falls ich das L2 in Zeile ändern   es gibt 3 auf „Null“ ist, dann nur alle   von L1, die nicht in L2 ist, aber keiner von   L2.

Es sieht aus wie Sie versuchen, die symmetrische Differenz zu berechnen, obwohl dies nicht der Fall mir klar, dass das ist, was die Ausübung Anfragen.

Wenn Sie es klug sein wollen, können Sie wahrscheinlich eine dritte Liste in der Funktion übergeben als Speicher zu dienen. Wenn L1 Elemente schieben das erste Element in den Akkumulator (und rufen rekursiv), wenn (null (member (first L1) L2)). Wenn L1 null ist, überprüfen Sie die Elemente von L2 gegen den Akkumulator Liste, das gleiche tun. Wenn L1 und L2 null sind, geben Sie den Akku-Liste.

Andere Tipps

In Lisp ist dies die Definition des Begriffs 'gesetzt Differenz':

set-difference list1 list2 &key (test #'eql) test-not (key #'identity)
   Function
   Returns a list of elements of list1 that do not appear in list2. 

Das ist Ihre modifizierte Umsetzung:

(defun list-diff (L1 L2)
  (cond
    ((null L1) L1)
    ((member (first L1) L2) (list-diff (rest L1) L2))
    (t (cons (first l1) (list-diff (rest l1) l2)))))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top