代码之家  ›  专栏  ›  技术社区  ›  Eric Schoonover thSoft

(在Lisp中定义(平均…)

  •  7
  • Eric Schoonover thSoft  · 技术社区  · 14 年前

    我只是在玩scheme/lisp,在想我该如何修改我自己的定义 average . 我不知道如何做一些我认为是必需的事情。

    • 定义接受任意数量参数的过程
    • 数一数这些论点
    • 将参数列表传递给(+)以将它们相加

    有没有人能举例说明 平均的

    5 回复  |  直到 14 年前
        1
  •  11
  •   Eli Barzilay    14 年前

    定义将是一个非常简单的单行线,但在不破坏它的情况下,您应该研究:

    • 一个“休息”的论点 (define (foo . xs) ...xs...) 定义 foo 作为一个函数,它接受任意数量的参数,并且它们可以作为 xs .

    • length 返回列表的长度。

    • apply 获取函数和值列表,并将函数应用于这些值。

    当你得到这个,你可以去更多:

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

    • exact->inexact 使浮点版本更有效。





    扰流器是:

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

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

    • 使用 福尔德尔 (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))))

        2
  •  3
  •   paxdiablo    10 年前

    在Common Lisp中,您可以执行以下操作:

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

    虽然我不知道 &rest 在所有Lisp实现中都可用。参考 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
  •  2
  •   Rainer Joswig mmmmmm    14 年前

    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)))
    
        4
  •  1
  •   Vijay Mathew Chor-ming Lung    14 年前

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

    (defun average (the-list)
      (let ((count 0) (sum 0))
        (dolist (n the-list)
          (incf count)
          (incf sum n))
        (/ sum count)))
    
        5
  •  1
  •   Felipe    10 年前

    在方案R5RS中:

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