Recursion 当传递一个负参数时,为什么我的代码被困在递归调用中?

Recursion 当传递一个负参数时,为什么我的代码被困在递归调用中?,recursion,math,scheme,lisp,Recursion,Math,Scheme,Lisp,我正试图在Scheme中实现一个递归过程,通过使用公式n^2=1+3+5+…+(n+n-1),在不使用乘法的情况下获取数字的平方。if(

我正试图在Scheme中实现一个递归过程,通过使用公式n^2=1+3+5+…+(n+n-1),在不使用乘法的情况下获取数字的平方。if( 当调用(Square1-2)时,它返回正确的值,但当我调用(Square1-2)时,它陷入递归调用

我想我设法把它缩小到了平方(+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))))))
(定义Square1
(λ(n)
(如果(=n0)
0)
(如果(
问题在于,如果,程序会卡在第二个
中,因为您的条件的结构方式,永远无法到达基本情况。我们应该将问题分为两部分:一个是检查案例的过程,当
n问题是,该过程卡在第二个
if
中,由于您的条件的结构方式,从未达到基本案例。我们应该将问题分为两部分:一个是检查案例的过程,当
n您需要阅读更多关于Scheme语法的内容时。对于初学者来说,代码中的第一个if是无用的,只有最后一个返回结果。为什么?因为要使它们有用,所有的IFs都必须有一个ELSE部分;有些Scheme方言甚至强迫你这样写,以避免像你现在面临的那样的混乱。@scarLópez公式也适用于5。@scarLópez公式是n^2=1+3+5+(n+n-1),所以如果n=5,(n+n-1)=(5+5-1)=9,意味着5^2=1+3+5+7+9=25。感谢这个例子,现在问题已经清楚了。我自由地格式化了代码,注意缩进代码和关闭括号的正确方法,这将使查找bug变得更容易。还有,检查我的答案!您需要阅读更多有关Scheme语法的信息。对于初学者来说,代码中的第一个if是无用的,只有最后一个返回结果。为什么?因为要使它们有用,所有的IFs都必须有一个ELSE部分;有些Scheme方言甚至强迫你这样写,以避免像你现在面临的那样的混乱。@scarLópez公式也适用于5。@scarLópez公式是n^2=1+3+5+(n+n-1),所以如果n=5,(n+n-1)=(5+5-1)=9,意味着5^2=1+3+5+7+9=25。感谢这个例子,现在问题已经清楚了。我自由地格式化了代码,注意缩进代码和关闭括号的正确方法,这将使查找bug变得更容易。还有,检查我的答案!你是说如果第三个被卡住了,不是第二个吗?我是说第二个,那是一个在没有基本案例的情况下会被执行的,只是为了效果哦,事实上,我看得太快了,我的错!你是说如果第三个被卡住了,不是第二个吗?我是说第二个,那是一个在没有基本案例的情况下会被执行的,只是为了效果哦,事实上,我看得太快了,我的错!
(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)))))
(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