2017-01-11 5 views
-1

Ich versuche, eine Funktion mit zwei Argumenten dieser Art zu schreiben:Auswechslungen in Common Lisp

substitutions (list_one, list_two) 

list_one hat immer dieses Formular (Buchstaben kann die Eingabe ändern sich entsprechend):

(1 ((1 2 ((1 2 r) (3 2 t) (4 3 c))) (3 4 ((5 6 y) (5 7 i))))) 

list_two hat immer dieses Formular (Zahlen können entsprechend der Eingabe aus):

(2 3 4 5 6) 

ich möchte in thi ersetzen s weg:

r-> 2 
t -> 3 
c -> 4 
y -> 5 
i -> 6 

Können Sie mir bitte helfen?

+5

SO ist kein freier Code-Writing Service. Sie müssen versuchen, das Problem selbst zu lösen. Veröffentlichen Sie Ihren Code und wir helfen Ihnen dann zu verstehen, was Sie falsch gemacht haben und wie Sie es beheben können. – Barmar

+0

Woher weiß es, welche Buchstaben zu welchen Nummern gehören? Ist es nur so, dass der erste Buchstabe in "list_1" die erste Nummer in "list_two" erhält, der zweite Buchstabe die zweite und so weiter? – Barmar

+0

Ich versuchte es in jeder Hinsicht und ich scheiterte, also entschied ich mich hier zu fragen! Mein Problem ist die mehr als eine Level-Liste. – Raynold

Antwort

0

Eine nicht so effiziente Lösung besteht darin, zuerst eine Liste aller Buchstaben in der ersten Baumstruktur (der ersten Liste) und dann LOOP über die Ergebnisse zu finden, die wiederholt SUBST aufrufen.

Um die Liste der nicht-numerischen Atome in der ersten Liste (die "Buchstaben") zu finden, müssen Sie die Baumstruktur (die erste Liste) sowohl auf der ERSTEN als auch auf der REST-Liste durchlaufen.

Ich hoffe, es hilft.

MA

+0

Vielen Dank !!! – Raynold

+0

Sie sind willkommen :) –

1

Wenn die Listen richtigen sind, können Sie sie mit dem loop Makro durchlaufen und die Argumente in der zugänglichen freie Variable Pop-off:

(defun template-replace (template replacements) 
    (labels ((iterate (template) 
      (loop :for element :in template 
        :collect 
        (cond ((consp element) (iterate element)) 
         ((symbolp element) (pop replacements)) 
         (t element))))) 
    (iterate template))) 


(template-replace '(1 rep (4 rep (9 rep)) rep) '(foot inch mm multiplied)) 
; ==> (1 foot (4 inch (9 mm)) multiplied) 
+0

Vielen Dank! Aber .. Gibt es einen anderen Weg, um das gleiche zu tun, ohne Etiketten und Argumente zu verwenden? – Raynold

+0

@Raynold Es gibt immer Möglichkeiten, es enger zu machen, aber warum sollten Sie es auf eine schwierigere und vielleicht suboptimale Weise lösen wollen? Ein Hinweis wäre, es rekursiv zu tun und es müssen zwei Werte zurückgegeben werden. Das Ergebnis und der übrig gebliebene Ersatz. Wenn die Vorlage "consp" ist, dann verwende "multiple-value-bind", um die Ergebnisse aus dem "Auto" zu erhalten, so dass du die "cdr" machen kannst. Im übrigen müssen Sie die Argumente zurückgeben, wenn das Element kein Symbol und null ist, während Sie den ersten und den Rest der Ersetzungen für den Rest zurückgeben. – Sylwester