(defun suma (L)
(setq var 0)
(do
((i 0 (+ i 1)))
((= i (length L)))
(+ var (nth i L)))
var)
为什么它总是返回0?
它不应该返回列表L的总和吗?
答案 0 :(得分:2)
info on how to do a good post不会修改其参数,因此,由于您永远不会修改df <- read.csv.sql("sample.csv", "select *, strftime('%d/%m/%Y', Date) as DateFormated from file where DateFormatted >= 1/2/2007 and DateFormatted <= 2/2/2007 ", sep=";")
,因此会返回其初始值0。
您需要将var
替换为(+ var (nth i L))
,等同于(incf var (nth i L))
。
请参阅+
。
请注意,您应该将(setq var (+ var (nth i L)))
与incf
绑定,而不是使用let
将其设为全局。
最重要的是,请注意您的算法在list参数的长度上是二次(因为setq
每次从头开始扫描您的列表。)
以下是一些更好的实现:
var
以下是错误的实施:
(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))
的问题是,如果提供的列表的长度大于nth
,它将失败。
答案 1 :(得分:0)
我认为这将是对完整学习体验的评论,但我无法在评论中加入代码。
有一种方法可以在不修改任何参数的情况下进行求和,这是通过递归方式进行的:
(defun recsum (list)
(if list
(+ (first list) (recsum (rest list)))
0))
此版本可以由编译器进行尾调用,并且与循环一样快:
(defun recsum2 (list &optional (accumulator 0))
(if list
(recsum2 (rest list) (+ accumulator (first list)))
accumulator))
您尝试做的事情可以通过以下do
来完成:
(defun suma (l)
(do
((var 0)
(i 0 (+ i 1)))
((= i (length l)) var)
(incf var (nth i l))))
但我们通常不会在do
的身体做任何事情,所以就像这样:
(defun suma (l)
(do
((i 0 (+ i 1))
(var 0 (+ var (nth i l))))
((= i (length l)) var)))
但是nth
和length
速度很慢,所以最好这样做:
(defun suma (l)
(do*
((var (first l) (+ var (first list)))
(list (rest l) (rest list)))
((null list) var)))
这个没有*
中的do
,并且在空列表中返回0:
(defun suma (l)
(do
((acc 0 (+ acc (first list)))
(list l (rest list)))
((null list) acc)))
但我最喜欢的是来自@sds的reduce
版本,它也可以在空列表中返回0:initial-value 0
编辑:recsum2没有返回任何内容,因此需要修复。