Lisp 中的 (定义 (平均 ....))

发布于 2024-09-09 01:02:12 字数 232 浏览 5 评论 0原文

我只是在玩scheme/lisp,并正在考虑如何纠正我自己对平均值的定义。我不确定如何做一些我认为需要的事情。

  • 定义一个接受任意数量参数的过程,对
  • 这些参数进行计数,
  • 将参数列表传递给(+)以将它们相加。

有人有定义平均值的示例吗?我似乎对 LISP 的了解不够,无法进行网络搜索来获取我正在寻找的结果。

I'm just playing around with scheme/lisp and was thinking about how I would right my own definition of average. I'm not sure how to do some things that I think are required though.

  • define a procedure that takes an arbitrary number of arguments
  • count those arguments
  • pass the argument list to (+) to sum them together

Does someone have an example of defining average? I don't seem to know enough about LISP to form a web search that gets back the results I'm looking for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

红衣飘飘貌似仙 2024-09-16 01:02:12

该定义将是一个非常简单的单行代码,但在不破坏它的情况下,您应该查看:

  • 一个“rest”参数 - 这个 (define (foo . xs) ...xs...)foo 定义为一个接受任意数量参数的函数,并且它们可以作为 xs 的值的列表提供。

  • length 返回列表的长度。

  • apply 接受一个函数和一个值列表,并将该函数应用于这些值。

当您明白这一点时,您可以了解更多信息:

  • 请参阅 foldl 函数,以避免在可能非常大的列表上应用列表(这在某些实现中很重要,其中参数列表的长度是有限的,但在 Racket 中不会有太大区别)。

  • 请注意,Racket 具有精确有理数,您可以使用 exact->inexact 来制作更高效的浮点版本。





剧透如下:

  • (define (average . ns) (/ (apply + ns) (length ns)))

  • 使其需要一个参数: (define (average n . ns) (/ (apply + n ns) (add1 (length ns) )))

  • < p>使用foldl(define (average n . ns) (/ (foldl + 0 (cons n ns)) (add1 (length ns))))
  • 使其使用浮点: (define (average n . ns) (/ (foldl + 0.0 (cons n ns)) (add1 (length ns))))

    使其

The definition would be a very simple one-liner, but without spoiling it, you should look into:

  • a "rest" argument -- this (define (foo . xs) ...xs...) defines foo as a function that takes any number of arguments and they're available as a list which will be the value of xs.

  • length returns the length of a list.

  • apply takes a function and a list of values and applies the function to these values.

When you get that, you can go for more:

  • see the foldl function to avoid applying a list on a potentially very big list (this can matter in some implementations where the length of the argument list is limited, but it wouldn't make much difference in Racket).

  • note that Racket has exact rationals, and you can use exact->inexact to make a more efficient floating-point version.





And the spoilers are:

  • (define (average . ns) (/ (apply + ns) (length ns)))

  • Make it require one argument: (define (average n . ns) (/ (apply + n ns) (add1 (length ns))))

  • Use foldl: (define (average n . ns) (/ (foldl + 0 (cons n ns)) (add1 (length ns))))

  • Make it use floating point: (define (average n . ns) (/ (foldl + 0.0 (cons n ns)) (add1 (length ns))))

遇见了你 2024-09-16 01:02:12

在 Common Lisp 中,看起来你可以这样做:

(defun average (&rest args)
  (when args
    (/ (apply #'+ args) (length args))))

尽管我不知道 &rest 是否适用于 Lisp 的所有实现。请参考此处

将该代码放入 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(正确)。

In Common Lisp, it looks like you can do:

(defun average (&rest args)
  (when args
    (/ (apply #'+ args) (length args))))

although I have no idea if &rest is available on all implementations of Lisp. Reference here.

Putting that code into GNU CLISP results in:

[1]> (defun average (&rest args)
       (when args
         (/ (apply #'+ args) (length args))))
AVERAGE
[2]> (average 1 2 3 4 5 6)
7/2

which is 3.5 (correct).

瞎闹 2024-09-16 01:02:12

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)))

Two versions in 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)))
调妓 2024-09-16 01:02:12

在Scheme中,我更喜欢使用列表而不是“rest”参数,因为rest参数使得实现如下所示的过程变得困难:将

> (define (call-average . ns)
     (average ns))
> (call-average 1 2 3) ;; => BANG!

任意数量的参数打包到列表中允许您对参数执行任何列表操作。您可以用更少的语法和更少的混乱做更多的事情。这是我的 average 方案版本,它采用“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)))

In Scheme, I prefer using a list instead of the "rest" argument because rest argument makes implementing procedures like the following difficult:

> (define (call-average . ns)
     (average ns))
> (call-average 1 2 3) ;; => BANG!

Packing arbitrary number of arguments into a list allows you to perform any list operation on the arguments. You can do more with less syntax and confusion. Here is my Scheme version of average that take 'n' arguments:

(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))))

Here is the same procedure in Common Lisp:

(defun average (the-list)
  (let ((count 0) (sum 0))
    (dolist (n the-list)
      (incf count)
      (incf sum n))
    (/ sum count)))
束缚m 2024-09-16 01:02:12

在方案R5RS中:

(define (average . numbers)  
    (/ (apply + numbers) (length numbers)))

In Scheme R5RS:

(define (average . numbers)  
    (/ (apply + numbers) (length numbers)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文