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)
(else
(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
(define (make-account balance passwd)
(let ((counter 0))
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount)) balance)
"餘額不足"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (call-the-cops amount)
"您已經嚐試輸入密碼7次了!不能再試!")
(define (dispatch pwd m)
(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
最後更新:2017-05-17 16:01:32