2017-04-11 9 views
0

나는 끝에 연산자를 사용하여리스트를 평가하는 계획 프로그램을 작성 중이다.스킴 프로그램이 중첩 목록을 평가하지 않습니까?

예 : (평가 '(1 2 +)) -> 3

내가 기본 운영자 작업 기능을 가지고 (+, -, *, /)하지만 문제는 내가 중첩이있을 때 온다 명부.

예 : ('평가 (1 (2 3 +) *)) -> (아무것도)

내가 조건을 실종?

(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))))))))) 

답변

0

하위 표현식에 대한 절차를 재귀 적으로 호출하는 것을 잊었습니다. 하나 만약

: 나는 3 포인터를

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

아, 지금 문제가 있습니다. 나는 내 진술이 어떤 이유로 든 밖으로 생각한 것으로 생각했다. 재귀 적으로 함수를 호출하는 것을 완전히 잊었다. 나는 Scheme을 처음 사용하기 때문에리스트가 어떻게 작동하는지 보는 것은 흥미 롭습니다. 고맙습니다! – Disc0nnect

1

: 덧붙여

(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))))))))) 

여기에 더 많은 관용구 프로그램을 다시 작성하는 방법이다 : 나는 간결함을 위해 ! 이름을 변경 한 경우, 여기를 참조하십시오 인수는 평가하지 않은 표현식입니다. 그러므로. 두 인수 모두에서 postfix을 실행해야합니다.

길이가 3이 아닌 경우 구현에서 if이 반환해야하는 값을 선택하도록합니다. 라켓의 경우 #<void>. 아마도 당신이 뭔가를 선택해야할까요? 실제로 얻을 여기에 인수가 자동으로 평가

(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 

공지 사항 : 당신이 한 말의 인수 고정 된 수를 가지고 있기 때문에

괄호에 대한 필요가 없습니다. 이것이 연결 언어 (스택 언어라고도 함)가이를 수행하는 방법입니다.