Lisp 小于n的正数和 (定义和(n) (如果(n

Lisp 小于n的正数和 (定义和(n) (如果(n,lisp,common-lisp,Lisp,Common Lisp,注意,您正在实现m=n-1,这允许一个简单的公式: (defun sum (n) (if (n<0) 0 n-1) ;; if n<0, add 0. Else add the next smallest. (sum (n-1))) 迭代版本也可以,在执行简单循环时不需要递归: (lambda (n) ;; You could inject n-1 on the formula to get n.(n-1)/2 ;; (like in Vatine's answe

注意,您正在实现m=n-1,这允许一个简单的公式:

(defun sum (n) 
  (if (n<0) 0 n-1) ;; if n<0, add 0. Else add the next smallest.
  (sum (n-1)))
迭代版本也可以,在执行简单循环时不需要递归:

(lambda (n)
  ;; You could inject n-1 on the formula to get n.(n-1)/2
  ;; (like in Vatine's answer), but here I just decrement 
  ;; the input  to show how to modify the local variable 
  ;; and reuse the formula linked above to sum up-to m.
  (decf n) 
  (if (minusp n) 
    0 
    (/ (* n (1+ n)) 2)))
关于您的代码:


  • 空间问题1
    n注意,您正在为m=n-1实现,这允许一个简单的公式:

    (defun sum (n) 
      (if (n<0) 0 n-1) ;; if n<0, add 0. Else add the next smallest.
      (sum (n-1)))
    
    迭代版本也可以,在执行简单循环时不需要递归:

    (lambda (n)
      ;; You could inject n-1 on the formula to get n.(n-1)/2
      ;; (like in Vatine's answer), but here I just decrement 
      ;; the input  to show how to modify the local variable 
      ;; and reuse the formula linked above to sum up-to m.
      (decf n) 
      (if (minusp n) 
        0 
        (/ (* n (1+ n)) 2)))
    
    关于您的代码:


    • 空间事项1
      n编辑:zerop>minssp检查负数,修复以适应OPs问题

      前一段时间我使用Lisp,但如果我没记错的话,会返回最后一个计算结果。问题的递归解决方案如下所示:

      (lambda (n) (loop :for x :below n :sum x))
      
      (defun sum (n) 
        (if (< n 0) 0 (- n 1)) 
        (sum (- n 1)))
      
      (定义和(n)
      
      (如果(Edit:zerop>minssp)检查负数,固定为适合OPs问题

      前一段时间我使用Lisp,但如果我没记错的话,会返回最后一个计算结果。问题的递归解决方案如下所示:

      (lambda (n) (loop :for x :below n :sum x))
      
      (defun sum (n) 
        (if (< n 0) 0 (- n 1)) 
        (sum (- n 1)))
      
      (定义和(n)
      
      (如果(在Lisp中,所有的比较器函数都是那样的函数,那么它需要是
      (-n1)
      (或者更简洁地说,
      (1-n)

      你不需要保留一个中间值,你可以简单地在你前进的过程中加起来。然而,这是复杂的,因为你要求和到“小于n”,而不是“到n”,所以你需要使用一个helper函数,如果你想递归地这样做的话

      更妙的是,如果您仔细阅读标准(例如,在网上很容易获得),您迟早会看到关于迭代的一章,
      循环
      工具可以做您想要的一切

      因此,如果我需要这样做,我会做:

       (defun sum (n)  
          (if (<= n 0) 0 ;;if n is less or equal than 0 return 0
              (+ (- n 1) (sum (- n 1))))) ;; else add (n-1) to sum of (n-1)
      

      如果我确实需要使其递归,我会使用以下方法:

      (defun my-sum (n)
         (loop for i below n
               sum i))
      
      (取消我的总和(n)
      (标签)(和内(i)
      (如果(

      这(几乎)等同于定义一个名为
      sum internal
      的全局函数,这对于调试来说可能更可取。但是,由于
      sum internal
      不太可能有任何其他用途,所以我将其设置为本地函数。

      在Lisp中,所有比较器函数都是这样的函数,所以它需要是
      (-n1)
      (或者更简洁地说,
      (1-n)

      你不需要保留一个中间值,你可以简单地在你前进的过程中加起来。然而,这是复杂的,因为你要求和到“小于n”,而不是“到n”,所以你需要使用一个helper函数,如果你想递归地这样做的话

      更妙的是,如果您仔细阅读标准(例如,在网上很容易获得),您迟早会看到关于迭代的一章,
      循环
      工具可以做您想要的一切

      因此,如果我需要这样做,我会做:

       (defun sum (n)  
          (if (<= n 0) 0 ;;if n is less or equal than 0 return 0
              (+ (- n 1) (sum (- n 1))))) ;; else add (n-1) to sum of (n-1)
      

      如果我确实需要使其递归,我会使用以下方法:

      (defun my-sum (n)
         (loop for i below n
               sum i))
      
      (取消我的总和(n)
      (标签)(和内(i)
      (如果(

      这(几乎)等同于定义一个名为
      sum internal
      的全局函数,这对于调试来说可能更可取。但是,由于
      sum internal
      不太可能有任何其他用途,所以我将其设置为本地函数。

      这是可行的。只是我需要将
      (+n(sum(-n1))
      更改为
      (+(-n1)(sum(-n1))
      ,因为根据问题,它是所有小于
      n
      的数字。如果您希望
      sum
      永远不会用负数调用,至少使用
      assert
      来防止意外的无限递归;-)您解决了问题
      0+1+2+…+n
      ,而OP有问题
      0+1+2+…+(n-1)
      递归调用
      sum
      的中间结果必须临时保存在内存中以计算中间和。这会阻止尾部调用优化,并使函数使用0(n)空间。对于足够大的
      n
      ,这将导致堆栈溢出错误。您可能希望使用累加器,但出于学习目的,这可能不是什么大问题。这是可行的。我需要将
      (+n(sum(-n1)))
      更改为
      (+n1)(sum(-n1)))
      相反,根据问题,所有的数字都小于
      n
      。如果你希望
      sum
      永远不会用负数调用,至少使用
      assert
      来防止意外的无限递归;-)你解决了问题
      0+1+2+…+n
      ,而OP有问题
      0+1+2+…+(n-1)
      sum的递归调用的中间结果必须临时保存在内存中,以计算中间和。这会阻止尾部调用优化,并使函数使用0(n)空间。对于足够大的
      n
      ,这将导致堆栈溢出错误。您可能希望使用累加器,但出于学习目的,这可能不是什么大问题。您是指
      (sum 4)
      ->
      10
      还是
      (sum 4)
      ->
      6
      ?换句话说,您需要对严格小于
      n
      的整数求和,还是不大于
      n
      的整数求和?后者
      (求和4)->6
      您是指
      (求和4)
      ->
      10
      还是
      (求和4)
      ->
      6
      ?换句话说,您需要对严格小于
      n
      的整数求和,还是不大于
      n
      的整数求和?后者
      (求和4)->6