2017-03-06 47 views
0

有人可以解釋爲什麼下面不起作用嗎?我正在通過SICP。這個練習要你創建一個計算結構對的函數。該程序用於三種結構,全部使用三對。SICP ex 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) 

第二遞歸不會有第一完成添加,因爲您添加到結合​​該助手的,因此當代碼重新開始再次做幫手它傳遞相同的版本它傳遞給第一次遞歸。

通過有一個let綁定,以便他助手總是更新相同的自由變量,您可以避免幾個版本的綁定存在。

相關問題