Scheme递归函数重复子表达式优化:绑定中间值可行方案问询
改进Scheme递归函数的重复计算问题
当然可以通过绑定中间值来优化这段代码啦!你担心let会引发递归调用的问题?其实完全没必要——这里我们用let绑定的只是(f (- n 1))的计算结果,不是递归定义函数,所以绝对安全。
用let优化的版本
这是最直接的改进方式,把重复计算的f(n-1)结果绑定到prev变量,只计算一次就能重复使用:
(define (f n) (if (zero? n) 1 (let ((prev (f (- n 1)))) (+ prev (/ 1 prev)))))
不用let的替代方案(内部定义)
如果确实有场景限制不能用let,还可以用Scheme的内部定义特性,效果完全一致:
(define (f n) (if (zero? n) 1 (begin (define prev (f (- n 1))) (+ prev (/ 1 prev)))))
这两种方式都解决了原代码的两个问题:
- 代码更优雅:通过变量名
prev清晰表达了这个值的含义,不用重复写冗长的递归调用表达式 - 效率更高:原代码每次
n>0时会递归调用两次f(n-1),现在只需要调用一次,避免了不必要的计算开销
内容的提问来源于stack exchange,提问作者user_163417
相关产品推荐
相关产品推荐

