在评论表上给我以下功能:
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2(mystery(- m 1)(- n 1))))
)))
前两个条件很简单,只是递归otherwise
令我感到困惑。在我看来,递归将继续,直到它们都等于零,这肯定不会返回总和。有人可以提供解释吗?
答案 0 :(得分:2)
首先,让我们更好地格式化代码,看看发生了什么:
(define (mystery m n)
(cond ((= m 0) n)
((= n 0) m)
(else (+ 2 (mystery (- m 1) (- n 1))))))
现在,请记住,cond
仅执行与true
的第一个条件相对应的操作(从上到下),其他操作将被忽略。如果所有条件都不是true
,则执行else
部分。要记住的重要一点是,只执行一个操作。
特别是,当 mystery
或m
变为零时,n
程序将停止,而两者变为零时。当其中一个达到零时,递归开始展开,返回总和。跟踪执行时可以看到这一点 - 例如,在Racket中:
(require racket/trace)
(trace mystery)
(mystery 3 2)
>(mystery 3 2)
> (mystery 2 1)
> >(mystery 1 0)
< <1
< 3
<5
答案 1 :(得分:2)
只是详细说明ÓscarLópez的答案(我不能在评论中对此进行格式化):我发现将这些类似的小递归数学函数写成数学通常很有用:
设m和n为自然数,然后
答案 2 :(得分:1)
我觉得最好的方法不是筑巢而是预先计算。查看基本情况,我们用零测试:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
因此,每次至少有一个参数为零时,它返回另一个参数。让我们尝试非零值,并记住第二个你看到我们已经完成的值,然后再用它的结果切换它:
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
因为我们知道基本情况总是返回另一个值,所以我们不需要预先计算它。这是一个做到这一点:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
我们可以概括将要发生的事情。 n
和m
的最低值将决定递归何时结束。在每一步,它将添加2并递归。因此,它是一种奇特的制作方式:
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
这又是添加两个数字的一种奇特方式,因为如果n > m
,那么2*m+(n-m) = m+m+(n-m) = m+n
答案 3 :(得分:0)
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2 (mystery (- m 1) (- n 1))))
)))
第一和第二个条件是显而易见的。
第三条陈述如何运作的说明:
1从m和n中取出,并在此函数外保持为2。 这一直持续到m为0或n为0。
答案 4 :(得分:0)
前2个案例很明显,其中一个数字为0的2个数字的总和等于另一个数字。
在最后一种情况下,在检查0的参数后,我们确信它们都是非0。 假设那个谜团返回其2个参数的总和,那么
(+ 2 (mystery (- arg1 1) (- arg2 1)))
将返回一个等于(mystery arg1 arg2)
的总和,并在其中一个参数为0时最终停止,返回所需的结果。
假设神秘回归,其两个参数的总和在这里是关键,被称为信仰的递归跳跃。 (谷歌)