如何为这个方案函数添加一个计数器
How to add a counter to this scheme function
我想添加一个计数器,这样我就可以看到迭代运行了多少次:
(define tolerance 0.01)
(define (close-enough? x y) (< (abs (- x y)) 0.001))
(define (fixed-point function starting-guess)
(define iter-count 0)
(define (evaluate num)
; these lines increment the counter using set!
(set! iter-count (+ iter-count 1))
(display iter-count) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
(fixed-point cos 1.0)
执行此操作的正确方法是什么?目前我已经添加了 define
和 set!
,因为我想不出让 let
工作的方法。有没有办法用 let
来做到这一点,或者建议的方法是什么?
或者,我想另一种方法是将它作为参数传递给迭代函数本身:
(define (fixed-point function starting-guess)
(define (evaluate num iteration-num)
(display iteration-num) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ 1 iteration-num)))))
(evaluate starting-guess 0))
就像num
一样,您只需将其添加到循环函数中即可:
(define (fixed-point function starting-guess)
;; prints progress
(define (print-progress iter-count)
(display iter-count)
(display " - ")
(display num)
(newline))
;; main calculating loop
(define (evaluate num iter-count)
(print-progress iter-count)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ iter-count 1)))))
;; start process with iter-count 1 since
;; we do increments after display
(evaluate starting-guess 1))
请注意,您的版本开始显示 0
,而您的 set!
版本以 1
开头。我通过从 1
而不是 0
.
开始来弥补这一点
您可以通过将功能添加到 function
:
来完全避免副作用 fixed-point
;; pure functional fixed-point
(define (fixed-point function starting-guess)
(define (evaluate num)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
;; makes a version of function that
;; reports its first argument and
;; number of times it's been called
(define (count-and-brag-calls f)
;; brag does whatever and
;; return the value
(define (brag v c)
(display c)
(display " - ")
(display v)
(newline)
v)
;; actual implementation
(let ((count 0))
(lambda (n)
(set! count (+ count 1))
(brag (f n) count))))
;; with verbose output
(fixed-point (count-and-brag-calls cos) 1.0)
;; without side effects gives exact same result without output
(fixed-point cos 1.0)
对于最小的编辑,只需将计数器的定义(绑定)移动到顶层,并在每次之前重置计数器 你打电话给fixed-point
:
(define iter-count 0) ;; here
(define (fixed-point function starting-guess)
;; (define iter-count 0) ;; commented-out
....
....
)
(begin
(set! iter-count 0)
(fixed-point ... ... ))
我想添加一个计数器,这样我就可以看到迭代运行了多少次:
(define tolerance 0.01)
(define (close-enough? x y) (< (abs (- x y)) 0.001))
(define (fixed-point function starting-guess)
(define iter-count 0)
(define (evaluate num)
; these lines increment the counter using set!
(set! iter-count (+ iter-count 1))
(display iter-count) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
(fixed-point cos 1.0)
执行此操作的正确方法是什么?目前我已经添加了 define
和 set!
,因为我想不出让 let
工作的方法。有没有办法用 let
来做到这一点,或者建议的方法是什么?
或者,我想另一种方法是将它作为参数传递给迭代函数本身:
(define (fixed-point function starting-guess)
(define (evaluate num iteration-num)
(display iteration-num) (display " - ") (display num) (display "\n")
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ 1 iteration-num)))))
(evaluate starting-guess 0))
就像num
一样,您只需将其添加到循环函数中即可:
(define (fixed-point function starting-guess)
;; prints progress
(define (print-progress iter-count)
(display iter-count)
(display " - ")
(display num)
(newline))
;; main calculating loop
(define (evaluate num iter-count)
(print-progress iter-count)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num (+ iter-count 1)))))
;; start process with iter-count 1 since
;; we do increments after display
(evaluate starting-guess 1))
请注意,您的版本开始显示 0
,而您的 set!
版本以 1
开头。我通过从 1
而不是 0
.
您可以通过将功能添加到 function
:
fixed-point
;; pure functional fixed-point
(define (fixed-point function starting-guess)
(define (evaluate num)
(let ((next-num (function num)))
(if (close-enough? num next-num)
next-num
(evaluate next-num))))
(evaluate starting-guess))
;; makes a version of function that
;; reports its first argument and
;; number of times it's been called
(define (count-and-brag-calls f)
;; brag does whatever and
;; return the value
(define (brag v c)
(display c)
(display " - ")
(display v)
(newline)
v)
;; actual implementation
(let ((count 0))
(lambda (n)
(set! count (+ count 1))
(brag (f n) count))))
;; with verbose output
(fixed-point (count-and-brag-calls cos) 1.0)
;; without side effects gives exact same result without output
(fixed-point cos 1.0)
对于最小的编辑,只需将计数器的定义(绑定)移动到顶层,并在每次之前重置计数器 你打电话给fixed-point
:
(define iter-count 0) ;; here
(define (fixed-point function starting-guess)
;; (define iter-count 0) ;; commented-out
....
....
)
(begin
(set! iter-count 0)
(fixed-point ... ... ))