2016-05-01 11 views
0

Was ich hier versuche, ist zunächst eine beliebige Liste flattern und dann diese Liste in meine Verschlüsselungsfunktion übergeben. Obwohl das nicht funktioniert und ich bin mir nicht sicher warum. Hier ist das, was ich bisher,(Common Lisp) Abflachung und Weitergabe Liste

(defun flatten (l) 
    (cond ((null l) l) 
     ((atom l) (list l)) 
     (t (loop for a in l appending (flatten a)))) 

) 



(defun encrypt(enctext) 
(flatten enctext) 

    (if(eq 'A (first enctext)) ;If the first charcater equals 'A'... 
     (progn     ;To allow multiple statements in an if statement 
     (prinC#\B)    ; First statement, print this character 
     (encrypt(rest enctext)))) ;Second statement, run function again passing the rest of the characters 

    (if(eq 'B (first enctext)) 
     (progn 
     (prinC#\C) 
     (encrypt(rest enctext)))) 


) 

Und das ist, wie ich den Aufruf der Verschlüsselungsfunktion

(encrypt '((A)(B)) 

Soll ich die „abzuflachen“ -Funktion innerhalb meiner „verschlüsseln“ Funktion aufrufen? Oder rufen Sie nach den rekursiven Aufrufen innerhalb der Funktion "flatten" "encrypt" auf? Und wie würde ich die gedrückte Liste richtig übergeben?

Antwort

1

ändert die Liste nicht destruktiv. Es erstellt eine neue Liste mit den abgeflachten Inhalten. Sie müssen den Rückgabewert anstelle des ursprünglichen ENCTEXT verwenden. Das wird leicht erreicht durch ENCRYPT Aufruf mag:

(encrypt (flatten '((A) (B)))) 

und Entfernen der Aufruf an FLATTEN von ENCRYPT. Hier ist eine etwas sauberere Version des Codes:

(defun encrypt (enctext) 
    (unless (endp enctext) 
    (princ (ecase (first enctext) ; I'm assuming the input shouldn't 
      (A #\B)    ; contain any symbols that aren't 
      (B #\C)))   ; handled here. Otherwise use CASE 
    (encrypt (rest enctext)))) ; instead of ECASE. 

Wenn Sie dies tun mögen, ohne einen separaten Funktionsaufruf um die Liste zu glätten, müssen Sie rekursiv absteigen in die Eingabeliste innerhalb ENCRYPT. Etwas wie:

(defun encrypt (enctext) 
    (unless (endp enctext) 
    (let ((first (first enctext))) 
     (if (atom first) 
      (princ (ecase first 
        (A #\B) 
        (B #\C))) 
      (encrypt first))) 
    (encrypt (rest enctext)))) 

(encrypt '((A) (B))) 
; BC 

Natürlich, wenn Sie diese mit Rekursion zu tun, keinen Grund haben zu wollen, sowohl für Tiefe und Breite, eine Schleife den Code machen würde viel klarer:

(defun encrypt (enctext) 
    (dolist (el enctext) 
    (if (atom el) 
     (princ (ecase el 
       (A #\B) 
       (B #\C))) 
     (encrypt el)))) 
+0

Danke ! Ich habe versucht, alles in eine Funktion zu integrieren, aber ich bin mir nicht einmal sicher, ob du das kannst. – Jcan1995

+0

@JoshuaCantero Ich fügte ein weiteres Beispiel hinzu, um es ohne Abflachung zu tun. – jkiiski

+0

Ja, mir ist aufgefallen, es hilft sehr. – Jcan1995