(defun sum (n)
(if (n<0) 0 n-1) ;; if n<0, add 0. Else add the next smallest.
(sum (n-1)))
到目前为止,我发布了类似的内容,但我不知道如何声明一个变量来存储我想要返回的总和。
答案 0 :(得分:2)
请注意,您正在为 m = n-1 实施1+2+...+m,其中包含一个简单的公式:
(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)))
迭代版本也可以工作,在执行简单循环时不需要递归:
(lambda (n) (loop :for x :below n :sum x))
关于您的代码:
空间事项 1 :n<0
被读作名称的符号&#34; N&lt; 0&#34; (默认为upcased)。同样适用于n-1
,这是一个名为&#34; N-1&#34;的符号。
(n<0)
将尝试运行名为n<0
的函数。 (n-1)
也是如此。
(minusp n)
或(< n 0)
。(1- n)
或(- n 1)
。如果您所写的内容写得正确,就像这样:
(defun sum (n)
(if (< n 0) 0 (- n 1))
(sum (- n 1)))
......仍有问题:
您希望(n-1)
实际递减n
,但此处if
仅计算一个值而不会产生副作用。
您无条件地调用(sum (n-1))
,这意味着:无限递归。前面的if
返回的值始终被忽略。
1 :有关详细信息,请查看成分和终止字符:2.1.4 Character Syntax Types
答案 1 :(得分:1)
编辑:zerop&gt;减去检查负数,修正以适合OPs问题
前段时间我使用过Lisp,但如果我记得正确,最后一次评估会被返回。解决问题的递归方法如下:
(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)
答案 2 :(得分:1)
在Lisp中,所有比较器函数都只是函数,因此需要(< n 0)
和(- n 1)
(或者更简洁,(1- n)
)。
您不需要保留中间值,您可以随时添加内容。但是,由于你总结为“小于n”而不是“到n”这一事实,这很复杂,所以你需要使用辅助函数,如果你想以递归方式执行此操作。
更好的是,如果你仔细阅读标准(易于在线提供,如the Common Lisp HyperSpec,你迟早会遇到关于迭代的章节,其中loop
设施会做你想要的一切。
所以,如果我需要这样做,我会做一个:
(defun my-sum (n)
(/ (* n (1- n)) 2))
或
(defun my-sum (n)
(loop for i below n
sum i))
如果我绝对需要让它递归,我会使用类似的东西:
(defun my-sum (n)
(labels ((sum-inner (i)
(if (< i 1)
0
(+ i (sum-inner (1- i))))))
(sum-inner (1- n))))
这几乎与定义名为sum-inner
的全局函数相同,这可能更适合于调试目的。但是,由于sum-inner
不太可能有任何其他用途,我将其设为本地。