2017-03-06 12 views
0

누군가 아래 설명 된 이유를 설명 할 수 있습니까? 나는 SICP를 통해 갈거야. 이 연습에서는 구조체 쌍을 계산하는 함수를 작성해야합니다. 이 프로그램은 3 개의 구조로 사용되며 모두 3 개의 쌍으로 구성됩니다.SICP 예 3.17 - 쌍을 세어보기 - 내 대답이 잘못 된 이유를 알 수 없습니다.

(define (count-pairs x) 
    (define (helper x encountered) 
    (if (or (not (pair? x)) (memq x encountered)) 
     0 
     (begin 
      (set! encountered (cons x encountered)) 
      (+ (helper (car x) encountered) 
      (helper (cdr x) encountered) 
      1)))) 

    (helper x (list))) 

올바른 해결 방법은 다음과 같습니다. 무엇이 잘못 될 수 있습니까? 나는 마주침이 약간 다르게 처리된다는 것을 알아 차리지 만 무엇이 잘못 될지를 안다.

(define (count-pairs x) 
    (let ((encountered '())) 
    (define (helper x) 
     (if (or (not (pair? x)) (memq x encountered)) 
      0 
      (begin 
      (set! encountered (cons x encountered)) 
      (+ (helper (car x)) 
       (helper (cdr x)) 
       1)))) 

    (helper x))) 

입력 사항 (l1 및 y1)은 아래에 표시되어 있지만 사용자가 직접 사용해 볼 필요는 없습니다.

; 4 pairs counted with wrong way, 3 with correct way 
(define l1 (list 1 2)) 
(define l2 (list 3)) 
(set-car! l1 l2) 
(set-cdr! l2 (cdr l1)) 

; 7 pairs counted with the wrong way, 3 with correct way 
(define y1 (list 1)) 
(define y2 (list 1)) 
(define y3 (list 1)) 
(set-car! y1 y2) 
(set-cdr! y1 y2) 
(set-car! y2 y3) 
(set-cdr! y2 y3) 

답변

1

답변에서 encountered이 도우미로 사용됩니다. 즉, helper을 사용할 때마다 자신의 버전이 encounter이됩니다. 이 양식을 읽을 때 : 코드가 다시 도우미를 할 재개되면

(+ (helper (car x) encountered) 
    (helper (cdr x) encountered) 
    1) 

당신이 이렇게 도우미가 가지고있는 바인딩에 추가 이후 처음으로 수행 한 추가가되지 않습니다 두 번째 재귀는 동일한 버전을 통과 그것은 첫 번째 재귀로 넘어갔습니다.

도우미가 항상 동일한 자유 변수를 업데이트하도록 바인딩을 사용하면 여러 버전의 바인딩이 존재하지 않게됩니다.