有人可以解释这段代码经历的递归吗?

时间:2013-09-28 19:56:01

标签: recursion scheme racket

(define (even x)  (= (modulo x 2) 0))
(define (twice x) (* x 2))
(define (half x)  (/ x 2))  

(define (rfmult a b)
    (cond ((= 0 a) 0)
          ((= 0 b) 0)
          ((even a) (twice (rfmult (half a) b)))
          (else     (+ b (twice (rfmult (half (- a 1)) b))))))

我理解为(rfmult 3 4)被调用,else语句被触发,之后(- 3 1)a取代并被切成两半然后它变成(rfmult 1 4)。在这一点上,我迷路了,因为如果它乘以2,它将永远不会结束。我似乎无法在脑海中理解它。

2 个答案:

答案 0 :(得分:2)

递归在'基本情况'结束(没有递归调用)。您的基本案例为ab0

使用'trace-define'

|(rfmult 3 4)
| (rfmult 1 4)
| |(rfmult 0 4)       ;; ends here
| |0
| 4
|12
像这样:

(trace-define (rfmult a b)    ; <= here
    (cond ((= 0 a) 0)
          ((= 0 b) 0)
          ((even a) (twice (rfmult (half a) b)))
          (else     (+ b (twice (rfmult (half (- a 1))b))))))

答案 1 :(得分:1)

我想我想出来......所以我们打电话(rfmult 100 5)

  1. 然后调用(rfmult(100/2 5)
  2. (50/2 5)* 2
  3. ((25-1)/ 2 5)* 2
  4. (12/2 5)* 2 + b
  5. (6 5)* 2
  6. (3 5)* 2
  7. ((3-1)/ 2 5)* 2
  8. (1 5)* 2 + b
  9. 0 <!/ LI>

    然后你通过递归向上追踪。

    因此,在(1 5)块中,b值变为15,因为5 * 2 + 5 = 15

    然后,(315)块b变为15 * 2 = 30

    然后,(6 30)b变为30 * 2 = 60

    然后,(12 60)60 * 2 + 5 = 125

    (25 125)125 * 2 =&gt; 250

    将我们带回(50 250)的第一个电话,其中250 * 2 = 500,这就是5 * 100的解决方案......

    如果这是错误的思考过程请纠正我!我现在已经坐在这个递归结构上大约2个小时了,我很高兴看到它有意义!