先载入题目给定的程序:
;;; 15.scm
(define (cube x) (* x x x))
(define (p x) (- (* 3 x) (* 4 (cube x))))
(define (sine angle)
(if (not (> (abs angle) 0.1))
angle
(p (sine (/ angle 3.0)))))
然后使用 trace 追踪 p
的调用,计算它的运行次数:
1 ]=> (load "15.scm")
;Loading "15.scm"... done
;Value: sine
1 ]=> (trace-entry p)
;Unspecified return value
1 ]=> (sine 12.15)
[Entering #[compound-procedure 11 p]
Args: 4.9999999999999996e-2]
[Entering #[compound-procedure 11 p]
Args: .1495]
[Entering #[compound-procedure 11 p]
Args: .4351345505]
[Entering #[compound-procedure 11 p]
Args: .9758465331678772]
[Entering #[compound-procedure 11 p]
Args: -.7895631144708228]
;Value: -.39980345741334
可以看到, p
共运行了 5 次。
在求值 (sine a)
的时候, a
每次都被除以 3.0
,而 sine
是一个递归程序,因此它的时间和空间复杂度都是 \(O(\log{a})\) 。
如果以上预测是正确的话,那么每当 a
增大一倍(准确地说,是乘以因子 3
), p
的运行次数就会增加一次,以下是相应的测试:
1 ]=> (sine 10) ; 5 次 p 调用
[Entering #[compound-procedure 11 p]
Args: .0411522633744856]
[Entering #[compound-procedure 11 p]
Args: .12317802324595176]
[Entering #[compound-procedure 11 p]
Args: .3620582351732319]
[Entering #[compound-procedure 11 p]
Args: .8963314023464528]
[Entering #[compound-procedure 11 p]
Args: -.19149217924571227]
;Value: -.5463890357524606
1 ]=> (sine 30) ; 6 次调用
[Entering #[compound-procedure 11 p]
Args: .0411522633744856]
[Entering #[compound-procedure 11 p]
Args: .12317802324595176]
[Entering #[compound-procedure 11 p]
Args: .3620582351732319]
[Entering #[compound-procedure 11 p]
Args: .8963314023464528]
[Entering #[compound-procedure 11 p]
Args: -.19149217924571227]
[Entering #[compound-procedure 11 p]
Args: -.5463890357524606]
;Value: -.9866890379958478
1 ]=> (sine 90) ; 7 次调用
[Entering #[compound-procedure 11 p]
Args: .0411522633744856]
[Entering #[compound-procedure 11 p]
Args: .12317802324595176]
[Entering #[compound-procedure 11 p]
Args: .3620582351732319]
[Entering #[compound-procedure 11 p]
Args: .8963314023464528]
[Entering #[compound-procedure 11 p]
Args: -.19149217924571227]
[Entering #[compound-procedure 11 p]
Args: -.5463890357524606]
[Entering #[compound-procedure 11 p]
Args: -.9866890379958478]
;Value: .8823180886403317