递归计算过程和迭代计算过程

        这次主要想通过几个sicp的题目来说明递归计算过程和迭代计算过程。

(1)阶乘

;递归计算过程
(define (factorial n)
  (if (= n 1)
      1
      (* (factorial (- n 1)) n)))

;迭代计算过程
(define (fact-iter counter result)
    (if (= counter 1)
        result
        (fact-iter (- counter 1) (* counter result))))
(define (factorial n)
  (fact-iter n 1))


(2)斐波拉契数列(普通方法)

;递归计算过程(cond 可以类比为C++中的switch,只是它还可以判断范围)
(define (Fib n)
  (cond 
    ((= n 0) 0)
    ((= n 1) 1)
    (else (+ (Fib (- n 1))
             (Fib (- n 2))))))

;迭代计算过程
(define (Fib-iter n a b)
  (if (= n 0)
      a
      (Fib-iter (- n 1) b (+ a b))))
(define (Fib n)
  (Fib-iter n 0 1))


(3)两个正整数加法(假设存在过程inc(递增1)和过程dec(递减1))

;n++
(define (inc n)
  (+ n 1))
;n--
(define (dec n)
  (- n 1))

;递归计算过程
(define (+ a b)
  (if (= 0 a)
      b
      (inc (+ (dec a) b))))
;迭代计算过程
(define (+ a b)
  (if (= a 0)
      b
      (+ (dec a) (inc b))))


(4)两个正整数乘法(假设存在过程double(翻倍)和过程halve(减半),基于这个两个已存在的过程,这个算法可以在对数步骤求出结果)

;2*n
(define (double n)
  (* n 2))
;n/2
(define (halve n)
  (/ n 2))
;判断是否为偶数
(define (even? n)
  (= 0 (remainder n 2)))

;需要注意的是:当b为偶数时, a*b = 2 * (a * (b / 2));当b为奇数时, a*b = a*(b-1) + a
;递归计算过程
(define (* a b)
  (cond 
    ((= b 0) a)
    ((even? b) (double (* a (halve b))))
    (else (+ a (* a (- n 1))))))

;迭代计算过程
(define (*-iter a b result)
  (cond 
    ((= b 0) result)
    ((even? b) (*-iter (double a) (halve b) result))
    (else (*-iter a (- b 1) (+ a result)))))
(define (* a b)
  (*-iter a b 0))


(5)求幂b^n(对数步骤)

;n^2
(define (square n)
  (* n n))

;需要注意的是:当n为偶数时, b^n = (b^(n/2))^2;当n为奇数时, b^n = b^(n-1) * b
;递归计算过程
(define (fast-expt b n)
  (cond
    ((= n 0) 1)
    ((even? n) (square (fast-expt b (/ n 2))))
    (else (* b (fast-expt b (- n 1))))))

;迭代计算过程
(define (fast-expt-iter b n result)
  (cond
    ((= n 0) result)
    ((even? n) (fast-expt-iter (square b) (/ n 2) result))
    (else (fast-expt-iter b (- n 1) (* b result)))))
(define (fast-expt b n)
  (fast-expt-iter b n 1))


(6)斐波拉契数列(对数步骤)

;这个算法基于一种比较巧妙的变换规则,用类似于fast-expt的方式压缩求解步骤。
;在fib-iter普通算法中,计算过程中的变换方式为a=b, b=a+b, 将此看作为T变换,也就是说Fib通过n次T变换就可以得到结果。
;而T变换可以看作是变换族Tpq中p=0且q=1的特殊情况,其中a = a*p + b*q, b = a*q + b*q + b*p
;可以证明我们应用Tpq变换两次,等同于应用Tp'q'变换一次,其中p' = p*p + q*q, q' = 2*p*q + q*q

;迭代计算过程
(define (fib-iter n a b p q)
  (cond
    ((= n 0) a)
    ((even? n) (fib-iter (/ n 2)
                         a
                         b
                         (+ (* p p) (* q q))
                         (+ (* 2 p q) (* q q))))
    (else (fib-iter (- n 1)
                    (+ (* a p) (* b q))
                    (+ (* a q) (* b q) (* b p))
                    p
                    q))))
(define (fib n)
  (fib-iter n 0 1 0 1))




原文地址:https://www.cnblogs.com/dyllove98/p/3249356.html