【问题标题】:Can someone explain the recursion that this code undergoes?有人可以解释这段代码经历的递归吗?
【发布时间】:2013-09-30 03:07:27
【问题描述】:
(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,它就永远不会结束。我只是似乎无法在脑海中理解它。

【问题讨论】:

  • 它是一种基于乘法分配性质的算法。对于两个数字 a 和 b,其中 c 是 1/2 a (2c = a),则 ab 等于 2cb,但也等于 2*(cb)。对于任何 ab,其中 d 比 a (d = a - 1) 小一,则 ab = a + (d * b)。请注意,编写的函数仅适用于整数。只需通过替代模型运行即可。 (rfmult 3 4) 变成 (+ 4 (twice (rfmult (half (- 3 1)) 4)) 简单地变成 (+ 4 ( (rfmult 1 4) 2)) 然后 (+ 4 (* ( + 4 (rfmult (half (- 1 1) 4)) 2)) 到 (+ 4 (* ( + 4 (rfmult 0 4)) 2)) 到 (+ 4 (* ( + 4 0)) 2) ) t0 (+ 4 (* 4 2)) 到 (+ 8 4) 到 12

标签: recursion scheme racket


【解决方案1】:

递归在“基本情况”(没有递归调用)处结束。你的基本情况是ab0

使用“跟踪定义”

|(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))))))

【讨论】:

    【解决方案2】:

    我想我想通了......所以让我们调用 (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!

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

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

    那么,(3 15) 块 b 变为 15 *2 = 30

    那么,(6 30) b 变为 30 * 2 = 60

    那么,(12 60) 60*2 + 5 = 125

    (25 125) 125 * 2 => 250

    这让我们回到 (50 250) 的第一次调用,其中 250*2 = 500,这就是 5*100 的解...

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 2020-02-04
      • 2015-09-14
      • 1970-01-01
      • 2011-08-20
      相关资源
      最近更新 更多