3-75 のこの回答もやっぱしあんましよろしくなくて,何がよろしくないかというと,この一つの関数の中には「平滑化」を行う部分と「0 をまたがる遷移があるかどうか判断」という二つの機能が混じってしまっています.
(define (make-zero-crossings input-stream last-value last-avgt) (let ((avpt (/ (+ (stream-car input-stream) last-value) 2))) (cons-stream (sign-change-detector avpt last-avpt) (make-zero-crossings (stream-cdr input-stream) (stream-car input-stream) avpt))))
そういうわけですから,まずは平滑化する関数を新たにつくる! 関数 smooth は連続する 2 つの要素の平均値をとったストリームを返してくれる関数になります.
(define (smooth s) (stream-map (lambda (a b) (/ (+ a b) 2)) s (cons-stream 0 s)))
smooth を使えば平滑化の部分はもはや必要なくなります.そうすると,make-zero-crossings はもっと簡単に書き下せる!
(define (make-zero-crossings input-stream) (let ((smoothed-stream (smooth input-stream))) (stream-map zero-crossing smoothed-stream (cons-stream 0 smoothed-stream)))) (define zero-crossings (make-zero-crossings sense-data))
非常にキレイだ!
追記
よくかんがえると,こっちのが良いよな.てか上のやつは題意みたしてないよな...
(define (make-zero-crossings input-stream) (stream-map zero-crossing input-stream (cons-stream 0 input-stream))) (define zero-crossings (make-zero-crossings (smooth sense-data)))