天天看點

sicp 3.1.1小節習題嘗試解答

這一節主要是介紹局部狀态變量,介紹了set!和begin的文法,看來ruby使用!号來表示改變變量值不是什麼新鮮主意。

習題3.1,不解釋了

;習題3.1

(define (make-accumulator init)

  (define (accumulator num)

    (set! init (+ init num))

    init)

  accumulator)

習題3.2,非常有趣的例子,在内部維持一個計數的變量即可,如果傳入的參數是特定的符号就傳回計數或者清0,如果不是,原過程調用。

;習題3.2

(define (make-monitored proc)

   (let ((counter 0))

  (define (proc-monitor args)

         (cond ((eq? args 'how-many-calls?) counter)

            ((eq? args 'reset-count) (begin (set! counter 0) counter))

            (else

              (begin (set! counter (+ counter 1)) (proc args)))))

  proc-monitor))

請注意,我的實作隻能針對有一個參數的過程,對于多個參數的過程我還不知道怎麼做。

習題3.3,passwd的局部狀态變量,在dispatch前比較下傳入的密碼是否與之一緻

;習題3.3

(define (make-account balance passwd)

  (define (withdraw amount)

    (if (>= balance amount)

        (begin (set! balance (- balance amount)) balance)

        "餘額不足"))

  (define (deposit amount)

    (set! balance (+ balance amount))

    balance)

  (define (dispatch pwd m)

    (if (eq? pwd passwd)

        (cond ((eq? m 'withdraw) withdraw)

              ((eq? m 'deposit) deposit)

               (error "unknow request--make-account" m)))

        (lambda(x) "incorrect password")))

  dispatch)

不一緻的時候,傳回一個匿名過程,僅僅是輸出消息incorrect password

習題3.4,在内部維持一個局部變量counter,用于計數密碼錯誤的次數,在dispatch前判斷counter是否等于7,如果是7就調用過程call-the-cops。

;習題3.4

  (let ((counter 0))

  (define (call-the-cops amount)

    "您已經嘗試輸入密碼7次了!不能再試!")

    (cond ((= 7 counter) call-the-cops)

          ((eq? pwd passwd)

           (cond ((eq? m 'withdraw) withdraw)

                 ((eq? m 'deposit) deposit)

                 (else

                   (error "unknow request--make-account" m))))

          (else

            (begin (set! counter (+ counter 1)) (lambda(x) "incorrect password")))))

 dispatch))

文章轉自莊周夢蝶  ,原文釋出時間2007-07-24