递归指数函数的迭代版本

时间:2013-11-05 15:41:44

标签: scheme racket

我基本上需要做一个我已经做过的以下函数的迭代版本:

(define (expo base e)
  (cond ((or (= base 1) (= e 0)) 1)
        (else (* base (expo base (- e 1))))))

我不知道怎么这样我需要帮助(在球拍/计划中))

3 个答案:

答案 0 :(得分:1)

您所要做的就是在累加器中传递结果。为此您需要一个额外的参数,有几种方法可以做到这一点,例如使用内部帮助程序:

(define (expo base e)
  ; helper procedure
  (define (iter e acc)
          ; now the base case returns the accumulator
    (cond ((or (= base 1) (= e 0)) acc) 
          ; see how the result is accumulated in the parameter
          (else (iter (- e 1) (* base acc)))))
  ; at the beginning, initialize the parameter in the right values
  (iter e 1))

或者,我们可以使用named let获得相同的效果:

(define (expo base e)
  (let iter ((e e) (acc 1))
    (cond ((or (= base 1) (= e 0)) acc)
          (else (iter (- e 1) (* base acc))))))

区分递归过程过程是件好事。以上两种实现都是递归过程:从语法上讲,很容易看出它们自称。但是它们生成的进程是迭代的:它们是以tail recursive样式编写的,所以在每次递归调用结束后,没有什么可做的,编译器可以优化掉递归调用和,出于所有实际目的,将其转换为迭代循环。

为了更好地理解迭代在Scheme中如何工作,请阅读奇妙的SICP书籍Procedures and the Processes They Generate

部分中有关此主题的更多信息。

答案 1 :(得分:1)

将这种递归函数转换为迭代的一般模式是使用累加器

(define (expo base e)
   (define (go base e accum)
      (if (or (= base 1) (= e 0))
          accum
          (go base (- e 1) (* accum base)))) ; Now this is tail recursion
    ???)

其中???go的相应初始值调用accum。注意在重复调用之前是如何在另一个调用(即*)内,但现在它是最后调用的东西。这允许程序在恒定的空间中运行。

答案 2 :(得分:0)

正如其他人所说,尾递归算法是一种迭代算法。但是,您可能需要一个明确的迭代算法吗?

(define (expo base exp)
  (do ((acc   1 (* acc base))
       (exp exp (- exp 1)))
      ((= 0 exp) acc))))

可以为(= base 1)添加一个条件 - 但是,正如所写的那样,这很简单。假设exp是一个整数。