使用do循环无法在Lisp中求和 [英] Cannot do sum in lisp with do loop
问题描述
(defun suma (L)
(setq var 0)
(do
((i 0 (+ i 1)))
((= i (length L)))
(+ var (nth i L)))
var)
为什么总是返回0?
它不应该返回列表L的总和吗?
Shouldn't it return sum of list L?
推荐答案
+
不会修改其参数,因此,由于您从未修改var
,因此将返回其初始值0.
+
does not modify its arguments, so, since you never modify var
, its initial value of 0 is returned.
您需要将(+ var (nth i L))
替换为与(setq var (+ var (nth i L)))
等效的(incf var (nth i L))
.
You need to replace (+ var (nth i L))
with (incf var (nth i L))
, of, equivalently, (setq var (+ var (nth i L)))
.
请参见 incf
.
Note that you should bind var
with let
instead of making it global with setq
.
最重要的是,请注意,您的算法在list参数的长度上是二次的(因为 nth
每次都从头开始扫描您的列表.
Most importantly, note that your algorithm is quadratic in the length of the list argument (because nth
scans your list every time from the start).
以下是一些更好的实现:
Here are some better implementations:
(defun sum-1 (l)
(reduce #'+ l))
(defun sum-2 (l)
(loop for x in l sum x))
(defun sum-3 (l)
(let ((sum 0))
(dolist (x l sum)
(incf sum x))))
这是一个坏实现:
(defun sum-4 (l)
(apply #'+ l))
The problem with sum-4
is that it will fail if the length of the supplied list is larger than call-arguments-limit
.
这篇关于使用do循环无法在Lisp中求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!