2017-04-11 6 views
0

Ich schreibe ein Schema-Programm, das eine Liste mit dem Operator am Ende auswertet.Scheme-Programm, das verschachtelte Listen nicht auswertet?

Beispiel: (bewerten ‚(1 2 +)) -> 3

Ich habe die Funktion für grundlegende Operatoren arbeitet (+, -, *, /), aber das Problem kommt, wenn ich ein verschachteltes habe Liste.

Beispiel: (bewerten ‚(1 (2 + 3) *)) -> (nichts)

Bin ich eine Bedingung fehlt?

(define (evaluate lis) 
    (cond 
     ((not (list? lis)) 
     lis) 
     ((list? lis) 
     (if (equal? (length lis) 3) 
      (cond 
      ((equal? (cddr lis) '(+)) 
      (+ (car lis) (car (cdr lis)))) 
      ((equal? (cddr lis) '(-)) 
      (- (car lis) (car (cdr lis)))) 
      ((equal? (cddr lis) '(*)) 
      (* (car lis) (car (cdr lis)))) 
      ((equal? (cddr lis) '(/)) 
      (/ (car lis) (car (cdr lis))))))))) 

Antwort

0

Sie haben vergessen, die Prozedur für die Unterausdrücke rekursiv aufzurufen. Sehen Sie hier, wo ich es ! Kürze wegen umbenannt haben:

(define (! lis) 
    (cond 
    ((not (list? lis)) 
    lis) 
    ((list? lis) 
    (if (equal? (length lis) 3) 
     (cond 
     ((equal? (cddr lis) '(+)) 
      (+ (! (car lis)) (! (cadr lis)))) 
     ((equal? (cddr lis) '(-)) 
      (- (! (car lis)) (! (cadr lis)))) 
     ((equal? (cddr lis) '(*)) 
      (* (! (car lis)) (! (cadr lis)))) 
     ((equal? (cddr lis) '(/)) 
      (/ (! (car lis)) (! (cadr lis))))))))) 

Übrigens ist hier, wie Sie das Programm neu schreiben könnte mehr idiomatisch:

(define (evaluate lis) 
    (cond 
    ((not (list? lis)) lis) 
    ((= (length lis) 3) 
    (let ((op (case (caddr lis) 
       ((+) +) 
       ((-) -) 
       ((*) *) 
       ((/) /)))) 
     (op (evaluate (car lis)) (evaluate (cadr lis))))))) 
+0

Oh, ich sehe das Problem jetzt. Ich dachte aus irgendeinem Grund, dass meine Aussagen von innen nach außen gingen. Ich habe völlig vergessen, die Funktion rekursiv aufzurufen. Ich bin neu bei Schema, daher ist es interessant zu sehen, wie die Listen hier funktionieren. Vielen Dank! – Disc0nnect

1

Ich habe 3 Zeiger:

Wenn man der Argumente sind ein Ausdruck, den Sie nicht bewerten. So. Sie müssen auch postfix für beide Argumente ausführen.

Wenn die Länge nicht 3 ist, lassen Sie die Implementierung wählen, welchen Wert die if zurückgeben sollte. Für Schläger sein #<void>. Vielleicht solltest du etwas wählen?

Da Sie eine feste Anzahl von Argumenten für Ihre Worte haben, gibt es keine Notwendigkeit für die Klammern:

(define (peval exprs) 
    (define primitives `((+ . ,+) (- . ,-) (* . ,*) (/ . ,/))) 
    (foldl (lambda (operator operands) 
      (let ((aproc (assq operator primitives))) 
      (if aproc 
       (cons ((cdr aproc) (cadr operands) (car operands)) 
         (cddr operands)) 
       (cons operator operands)))) 
     '() 
     exprs)) 

(peval '(2 3 4 + *)) ; (2 (3 4 +) *) == 14 

Beachten Sie, dass hier die Argumente bekommt automatisch tatsächlich auswertet. So machen es die Verkettungssprachen (auch bekannt als Stapelsprachen).

Verwandte Themen