【问题标题】:SICP - Code improvement with more abstractionSICP - 更抽象的代码改进
【发布时间】:2017-01-13 05:29:32
【问题描述】:

我正在使用 SICP 书,我做了这个练习:

1.11 函数 f 由 f(n) = n 如果 n 3. 编写一个通过递归过程计算 f 的过程。编写一个通过迭代过程计算 f 的过程。

递归过程很简单。迭代更难。

我做了这个代码:

(define (f-ltail n)
  (f-iter 0 n))

(define (f-iter produto n)
  (define counter (- n 2))  
  (cond ((< n 3) n)
        ((= counter 0) produto)
        (else (+ produto (+ (f-iter produto (- n 1))
                            (* 2 (f-iter produto (- n 2)))
                            (* 3 (f-iter produto (- n 3))))))))

我的教授一直说我们应该避免定义不需要定义的东西。

这个定义真的需要吗?

(define counter (- n 2)) 

如果没有,如何消除这段代码?

【问题讨论】:

  • 为什么我的帖子被否决了?我是堆栈溢出的新手,无法弄清楚...
  • 既然你只是在一个地方使用counter,看到(= (- n 2) 0),那么这只是一个困难的方法来做(= n 2)因为第一个术语命中所有小于3的东西,我们知道n 在第二个任期内不能是2,因为它是3 或更高版本。迭代过程将是尾递归的,因此您的所有计算都应该基于参数。
  • 让我们从f-iter 不生成迭代过程的事实开始:因为它必须处于尾调用位置。其实应该是线性迭代的过程,但是你的过程会导致树递归。只需查看 SICP 中的斐波那契示例,并以与他们相同的方式更正您的代码。
  • 我认为如果你“向上递归”,这个会容易得多。

标签: refactoring iteration lisp racket sicp


【解决方案1】:

这本书 gives an example 迭代计算斐波那契数列。

(define (fib n)
  (fib-iter 1 0 n))

(define (fib-iter a b count)
  (if (= count 0)
      b
      (fib-iter (+ a b) a (- count 1))))

请注意,不是在fib-iter 函数中定义计数器变量,而是将参数传递给函数以跟踪该值。您可以在函数中遵循相同的模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多