2015/09/08 21:51

# 练习3-1

## 原文

Exercise 3.1. An accumulator is a procedure that is called repeatedly with a single numeric argument and accumulates its arguments into a sum. Each time it is called, it returns the currently accumulated sum. Write a procedure make-accumulator that generates accumulators, each maintaining an independent sum. The input to make-accumulator should specify the initial value of the sum; for example
(define A (make-accumulator 5))
(A 10)
15
(A 10)
25

## 代码

(define (make-accumulator value) (lambda (add-value) (set! value (+ value add-value)) value))

# 练习3-2

## 原文

Exercise 3.2. In software-testing applications, it is useful to be able to count the number of times a given procedure is called during the course of a computation. Write a procedure make-monitored that takes as input a procedure, f, that itself takes one input. The result returned by make-monitored is a third procedure, say mf, that keeps track of the number of times it has been called by maintaining an internal counter. If the input to mf is the special symbol how-many-calls?, then mf returns the value of the counter. If the input is the special symbol reset-count, then mf resets the counter to zero. For any other input, mf returns the result of calling f on that input and increments the counter. For instance, we could make a monitored version of the sqrt procedure:
(define s (make-monitored sqrt))
(s 100)
10
(s ‘how-many-calls?)
1

## 分析

1.一个参数f
2.一个内部计数器count-call
3.返回一个过程，并且其有一个输入。
4.如果返回过程的输入为how-many-call?则返回count-call；

1.一开始要用let将count-call记为0
2.在输入为reset-count的时，用set!将count-call清0
3.在其他情况时，除了用set!做加1处理外，还要同时将f应用于input。

## 代码

(define (make-monitored f) (let ((count-call 0)) (lambda (input) (cond ((eq? input 'how-many-calls?) count-call) ((eq? input 'reset-count) (begin (set! count-call 0) count-call)) (else (begin (set! count-call (+ 1 count-call)) (f input)))))))

## 测试

(define (make-monitored f) (let ((count-call 0)) (lambda (input) (cond ((eq? input 'how-many-calls?) count-call) ((eq? input 'reset-count) (begin (set! count-call 0) count-call)) (else (begin (set! count-call (+ 1 count-call)) (f input)))))))
;Value: make-monitored

(define (cube x) (* x x x))
;Value: cube

(define z (make-monitored cube))
;Value: z

(z 10)
;Value: 1000

(z 10)
;Value: 1000

(z 'how-many-calls?)
;Value: 2

# 练习3-3

## 原文

Exercise 3.3. Modify the make-account procedure so that it creates password-protected accounts. That is, make-account should take a symbol as an additional argument, as in
The resulting account object should process a request only if it is accompanied by the password with which the account was created, and should otherwise return a complaint:
60

## 分析

2.输出错误信息的函数display-warning-message

;The procedure #[compound-procedure 13 display-warning-message] has been called with 1 argument; it requires exactly 0 arguments.

## 代码

(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount) balance) (define (correct-password? input-password) (eq? password input-password)) (define (display-warning-message msg) (display "Incorrect password")) (define (dispatch input-password m) (if (correct-password? input-password) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknow request -- MAKE-ACCOUNT" mode))) display-warning-message)) dispatch)

## 测试

(define acc (make-account 100 'secret-password)) ;Value: acc ((acc 'secret-password 'withdraw) 40) ;Value: 60 ((acc 'some-other-password 'deposit) 60) Incorrect password ;Unspecified return value

# 练习3-4

## 原文

Exercise 3.4. Modify the make-account procedure of exercise 3.3 by adding another local state variable so that, if an account is accessed more than seven consecutive times with an incorrect password, it invokes the procedure call-the-cops.

## 分析

1.尝试次数try-times
2.上一题的display-warning-message做修改：用set!将尝试次数try-times加1，大于7次时调用过程call-the-cops

## 代码

(define (make-account balance password) (let ((try-times 0)) (define (call-the-cops) (error "You try too much times, calling the cops ...")) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- blance amount)) balance) (define (deposit amount) (set! balance (+ balance amount))) (define (correct-password? input-password) (eq? password input-password)) (define (display-warning-message msg) (display "Incorrect password")) (define (dispatch input-password m) (if (password-match? input-password) (begin (set! try-times 0) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknow request -- MAKE-ACCOUNT" mode)))) (begin (set! try-times (+ 1 try-times)) (if (>= try-times 7) (call-the-cops) display-warning-message)))) dispatch))

## 测试

(define acc (make-count 100 'secret-password))

;Value: acc

;Unspecified return value

;Unspecified return value

;Unspecified return value

;Unspecified return value

;Unspecified return value

;Unspecified return value

;You try too much times, calling the cops ...


http://blog.csdn.net/nomasp

0
0 收藏

0 评论
0 收藏
0