Scheme 方案标准差

Scheme 方案标准差,scheme,racket,Scheme,Racket,我试图得到一个返回单个列表的标准偏差的函数,我的代码运行得很好,但是我想学习如何在代码中使用map、apply和filter。到目前为止,我已经在平均函数上使用了apply,但我无法在代码的其余部分使用它们 (define (average li) (/ (apply + li) (length li))) (define (summation li avg) (if (null? li) 0 (+ (* (- (car li) avg)

我试图得到一个返回单个列表的标准偏差的函数,我的代码运行得很好,但是我想学习如何在代码中使用map、apply和filter。到目前为止,我已经在平均函数上使用了apply,但我无法在代码的其余部分使用它们

(define (average li)
  (/ (apply + li) (length li)))

(define (summation li avg)
  (if (null? li)
    0
    (+  
       (* (- (car li) avg) 
          (- (car li) avg))
    (summation (cdr li) avg))))

(define (sd li)
    (sqrt
        (/  
          (summation li (average li))
          (- (length li) 1))))

我觉得map可以用在求和函数中,但它会犯一个很大的错误。

你可以用

虽然您在这里提供的这些程序看起来很简单,但是您应该考虑它们的实现的后果。例如,我确信您可以编写自己的
length
函数

(define (length li)
  (if (null? li)
      0
      (+ 1 (length (cdr li)))))
您可以使用
(apply+li)
来计算输入列表的总和,但我相信您会意识到这是一个聪明的方法,可以替代我们简单的递归解决方案

(define (sum li)
  (if (null? li)
      0
      (+ (car li)
         (sum (cdr li)))))
给定
sum
length
,我们实现
average

(define (average li)
  (/ (sum li)
     (length li)))
你看到这里的问题了吗
sum
length
都迭代输入列表。然后我们继续写
sd

(define (sd li)
  (sqrt (/ (summation li
                      (average li))
           (- (length li) 
              1))))
你看到问题如何恶化了吗?我们知道
average
已经对输入列表
li
进行了两次遍历,
summation
再次对其进行遍历,并注意到对
length
的另一个调用–在
sd
返回其结果之前,我们已经对
li进行了4次迭代

让我们倒带一点。看看
average
,如果我们能用某种方法将
li
的元素相加并同时计数,那不是很好吗?我们可以

(define (average li (return /))
  (if (null? li)
      (return 0 0)
      (average (cdr li)
               (lambda (sum count)
                 (return (+ sum (car li))
                         (+ count 1))))))


(average '(1))     ;; 1
(average '(1 2))   ;; 1 1/2
(average '(1 2 3)) ;; 2
(average '())      ;; Error: division by zero

使用此技术,您可以执行几乎任何复杂度的转换。使用此样式编写
sd
留给读者作为练习。

您可以使用

虽然您在这里提供的这些程序看起来很简单,但是您应该考虑它们的实现的后果。例如,我确信您可以编写自己的
length
函数

(define (length li)
  (if (null? li)
      0
      (+ 1 (length (cdr li)))))
您可以使用
(apply+li)
来计算输入列表的总和,但我相信您会意识到这是一个聪明的方法,可以替代我们简单的递归解决方案

(define (sum li)
  (if (null? li)
      0
      (+ (car li)
         (sum (cdr li)))))
给定
sum
length
,我们实现
average

(define (average li)
  (/ (sum li)
     (length li)))
你看到这里的问题了吗
sum
length
都迭代输入列表。然后我们继续写
sd

(define (sd li)
  (sqrt (/ (summation li
                      (average li))
           (- (length li) 
              1))))
你看到问题如何恶化了吗?我们知道
average
已经对输入列表
li
进行了两次遍历,
summation
再次对其进行遍历,并注意到对
length
的另一个调用–在
sd
返回其结果之前,我们已经对
li进行了4次迭代

让我们倒带一点。看看
average
,如果我们能用某种方法将
li
的元素相加并同时计数,那不是很好吗?我们可以

(define (average li (return /))
  (if (null? li)
      (return 0 0)
      (average (cdr li)
               (lambda (sum count)
                 (return (+ sum (car li))
                         (+ count 1))))))


(average '(1))     ;; 1
(average '(1 2))   ;; 1 1/2
(average '(1 2 3)) ;; 2
(average '())      ;; Error: division by zero
使用此技术,您可以执行几乎任何复杂度的转换。使用此样式编写
sd
留给读者作为练习