Lisp 小于n的正数和 (定义和(n) (如果(n
注意,您正在实现m=n-1,这允许一个简单的公式: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
(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)
) 你不需要保留一个中间值,你可以简单地在你前进的过程中加起来。然而,这是复杂的,因为你要求和到“小于n”,而不是“到n”,所以你需要使用一个helper函数,如果你想递归地这样做的话 更妙的是,如果您仔细阅读标准(例如,在网上很容易获得),您迟早会看到关于迭代的一章,(1-n)
工具可以做您想要的一切 因此,如果我需要这样做,我会做:循环
或 如果我确实需要使其递归,我会使用以下方法:(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
不太可能有任何其他用途,所以我将其设置为本地函数。在Lisp中,所有比较器函数都是这样的函数,所以它需要是sum internal
和(
(或者更简洁地说,(-n1)
) 你不需要保留一个中间值,你可以简单地在你前进的过程中加起来。然而,这是复杂的,因为你要求和到“小于n”,而不是“到n”,所以你需要使用一个helper函数,如果你想递归地这样做的话 更妙的是,如果您仔细阅读标准(例如,在网上很容易获得),您迟早会看到关于迭代的一章,(1-n)
工具可以做您想要的一切 因此,如果我需要这样做,我会做:循环
或 如果我确实需要使其递归,我会使用以下方法:(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
,而OP有问题0+1+2+…+n
递归调用0+1+2+…+(n-1)
的中间结果必须临时保存在内存中以计算中间和。这会阻止尾部调用优化,并使函数使用0(n)空间。对于足够大的sum
,这将导致堆栈溢出错误。您可能希望使用累加器,但出于学习目的,这可能不是什么大问题。这是可行的。我需要将n
更改为(+n(sum(-n1)))
相反,根据问题,所有的数字都小于(+n1)(sum(-n1)))
。如果你希望n
永远不会用负数调用,至少使用sum
来防止意外的无限递归;-)你解决了问题assert
,而OP有问题0+1+2+…+n
sum的递归调用的中间结果必须临时保存在内存中,以计算中间和。这会阻止尾部调用优化,并使函数使用0(n)空间。对于足够大的0+1+2+…+(n-1)
,这将导致堆栈溢出错误。您可能希望使用累加器,但出于学习目的,这可能不是什么大问题。您是指n
->(sum 4)
还是10
->(sum 4)
?换句话说,您需要对严格小于6
的整数求和,还是不大于n
的整数求和?后者n
您是指(求和4)->6
->(求和4)
还是10
->(求和4)
?换句话说,您需要对严格小于6
的整数求和,还是不大于n
的整数求和?后者n
(求和4)->6
- 空间事项1: