学习LISP - 定义stdev函数

时间:2016-09-11 17:26:52

标签: lisp common-lisp

我是LISP的新手(请原谅我任何愚蠢的错误)和今年的第一个实验室:

定义一个函数,STDEV将计算数字列表的标准偏差(查找公式)

我写了这段代码,但我不知道为什么它拒绝工作:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))


(setq a '(1 2 3 4 5))

(STDEV a)

但在运行时会产生错误:“(1 2 3 4 5)不是数字”

我相信我已经正确地模仿了标准偏差公式(虽然我不会过去自己做出一个愚蠢的错误),但为什么我的程序不喜欢我给它评估的数字列表?这种新编码方式的输入很可能是一个简单的错误,但是非常感谢任何和所有的帮助!

2 个答案:

答案 0 :(得分:5)

使用缩进。我已经编辑了你的问题:

(defun stdev (x)
  (sqrt (/ (apply '+ (expt (- x (/ (apply '+ x)
                                   (length x)))
                           2))
           (length x))))

expt会返回一个数字。你打电话给(apply '+ some-number)

您还要从列表中减去一个数字。

为什么?

一般情况下,我建议使用Lisp监听器(也称为REPL)来使用代码:

计算平均值:

CL-USER 21 > (let ((l (list 1 2 3 4 5)))
               (/ (reduce #'+ l)
                  (length l)))
3

使用mapcar

减去平均值和平方
CL-USER 22 > (mapcar (lambda (item)
                       (expt (- item 3) 2))
                     (list 1 2 3 4 5))
(4 1 0 1 4)

将方差计算为上述平均值:

CL-USER 23 > (let ((l (list 4 1 0 1 4)))
               (/ (reduce #'+ l)
                  (length l)))
2

取平方根得到标准偏差

CL-USER 24 > (sqrt 2)
1.4142135

然后,您只需将其组合成几个函数:averagevariancestandard-deviation

答案 1 :(得分:1)

- a ...是您的列表时,您正在使用a

不是一个完整的答案,因为这是作业,但是:你想首先计算均值,你可以实现一个sum函数,你需要两次,有一个折叠,你可以应用一个辅助函数或lambda表达式使用地图到列表的每个元素。