我正在玩scheme / lisp,并且正在考虑如何改正我自己对average
的定义。我不知道如何做一些我认为必需的事情。
有人有定义average
的例子吗?我似乎对LISP的了解不足以形成一个网络搜索,可以找回我正在寻找的结果。
答案 0 :(得分:11)
定义将是一个非常简单的单行,但不破坏它,你应该看看:
一个“rest”参数 - 这个(define (foo . xs) ...xs...)
将foo
定义为一个函数,它接受任意数量的参数,它们作为一个列表可用,它将是{{ 1}}。
xs
返回列表的长度。
length
获取函数和值列表,并将函数应用于这些值。
当你得到它时,你可以追求更多:
请参阅apply
函数以避免在可能非常大的列表中应用列表(这在参数列表的长度有限的某些实现中很重要,但它不会有太大区别在球拍)。
请注意,Racket具有完全合理性,您可以使用foldl
制作更高效的浮点版本。
剧透者是:
exact->inexact
需要一个参数:(define (average . ns) (/ (apply + ns) (length ns)))
使用(define (average n . ns) (/ (apply + n ns) (add1 (length ns))))
:foldl
使用浮点数:(define (average n . ns) (/ (foldl + 0 (cons n ns)) (add1 (length ns))))
答案 1 :(得分:3)
在Common Lisp中,看起来你可以做到:
(defun average (&rest args) (when args (/ (apply #'+ args) (length args))))
虽然我不知道所有Lisp实现是否都有&rest
。参考here。
将该代码放入GNU CLISP会导致:
[1]> (defun average (&rest args) (when args (/ (apply #'+ args) (length args)))) AVERAGE [2]> (average 1 2 3 4 5 6) 7/2
这是3.5(正确)。
答案 2 :(得分:2)
Common Lisp中有两个版本:
(defun average (items)
(destructuring-bind (l . s)
(reduce (lambda (c a)
(incf (car c))
(incf (cdr c) a)
c)
items
:initial-value (cons 0 0))
(/ s l)))
(defun average (items &aux (s 0) (l 0))
(dolist (i items (/ s l))
(incf s i)
(incf l)))
答案 3 :(得分:1)
在Scheme中,我更喜欢使用列表而不是“rest”参数,因为rest参数使得实现如下的过程变得困难:
> (define (call-average . ns)
(average ns))
> (call-average 1 2 3) ;; => BANG!
将任意数量的参数打包到列表中允许您对参数执行任何列表操作。你可以用更少的语法和混乱来做更多事情。这是average
的Scheme版本,带有'n'个参数:
(define (average the-list)
(let loop ((count 0) (sum 0) (args the-list))
(if (not (null? args))
(loop (add1 count) (+ sum (car args)) (cdr args))
(/ sum count))))
以下是Common Lisp中的相同过程:
(defun average (the-list)
(let ((count 0) (sum 0))
(dolist (n the-list)
(incf count)
(incf sum n))
(/ sum count)))
答案 4 :(得分:1)
在Scheme R5RS中:
(define (average . numbers)
(/ (apply + numbers) (length numbers)))