我正在尝试在Scheme中实现一个递归过程,该过程采用数字n的平方而不使用公式n ^ 2 = 1 + 3 + 5 + ... +(n + n-1)进行乘法。如果参数为负数,则if( 调用(Square1 2)时,它将返回正确的值,但是当我调用(Square1 -2)时,它将陷入递归调用中。 我认为我设法将其范围缩小到Square1(+ n -1)作为问题的原因,但是我不确定为什么这会导致问题。我尝试使用Java中的相同逻辑对此进行编程,看来我的逻辑是正确的。这是我的第一门功能语言,所以可能有些我不了解。 (define Square1
(lambda (n)
(if (= n 0)
0)
(if (< n 0)
(Square1 (* -1 n)))
(if (= n 1)
1
(+ (+ (+ n n) -1) (Square1 (+ n -1))))))
答案 0 :(得分:2)
问题在于该过程被卡在第二个if
中,由于条件的结构方式,该过程永远无法达到基本情况。我们应该将问题分为两部分:一个过程用于检查n <= 0
时的情况,另一个过程用于在一般情况下执行循环。
请注意,在Scheme过程中,仅最后一个表达式的结果被返回 -当然可以执行其他的表达式,但是它们的结果将被忽略。对于if
表达式,对其进行结构化,使其始终具有“ else”部分。话虽如此,这应该起作用:
(define (aux n)
(if (= n 1)
1
(+ (+ (+ n n) -1)
(aux (+ n -1)))))
(define (square1 n)
(if (= n 0)
0
(if (> n 0)
(aux n)
(aux (- n)))))
以上解决方法是正确的,但不是惯用的 。我们可以做得更好!
aux
过程应该在主过程内部,因为它不会在其他任何地方使用if
更好,而不是嵌套cond
zero?
,positive?
,sub1
这是一个看起来比较惯用的答案,它的工作原理与第一个相同:
(define (square1 n)
(define (aux n acc)
(if (= n 1)
acc
(aux (sub1 n) (+ acc (sub1 (+ n n))))))
(cond ((zero? n) 0)
((positive? n) (aux n 1))
(else (aux (- n) 1))))
无论哪种方式,它都能按预期工作:
(square1 -4)
=> 16
(square1 -3)
=> 9
(square1 -2)
=> 4
(square1 -1)
=> 1
(square1 0)
=> 0
(square1 1)
=> 1
(square1 2)
=> 4
(square1 3)
=> 9
(square1 4)
=> 16