Scheme 如何在球拍上打方块

Scheme 如何在球拍上打方块,scheme,racket,Scheme,Racket,这是我的密码: (define (squares 1st) (let loop([1st 1st] [acc 0]) (if (null? 1st) acc (loop (rest 1st) (* (first 1st) (first 1st) acc))))) 我的测试是: (test (sum-squares '(1 2 3)) => 14 ) 它失败了 例如,函数输入是一个数字[1,2,3]列表,我需要将每个数字平方,然后将它们相加,输

这是我的密码:

(define (squares 1st)
  (let loop([1st 1st] [acc 0])
    (if (null? 1st)
        acc
        (loop (rest 1st) (* (first 1st) (first 1st) acc)))))
我的测试是:

(test (sum-squares '(1 2 3)) => 14 )
它失败了

例如,函数输入是一个数字[1,2,3]列表,我需要将每个数字平方,然后将它们相加,输出-number。
如果输入正确答案,测试将返回#t。

这与您的测试非常相似,但有一个转折点:这里我们添加,而不是乘法。每个元素在相加之前都会被平方:

(define (sum-squares lst)
  (if (empty? lst)
      0
      (+ (* (first lst) (first lst))
         (sum-squares (rest lst)))))
与前面一样,也可以使用尾部递归编写过程:

(define (sum-squares lst)
  (let loop ([lst lst] [acc 0])
    (if (empty? lst)
        acc
        (loop (rest lst) (+ (* (first lst) (first lst)) acc)))))
您必须认识到,两种解决方案共享相同的结构,其变化是:

  • 我们使用
    +
    组合答案,而不是
    *
  • 在添加当前元素之前,我们将其平方化
    (第一个lst)
  • 添加列表的基本情况是
    0
    (乘法是
    1
最后,在实际应用程序中,您不应该使用显式递归,相反,我们将使用高阶过程来编写解决方案:

(define (square x)
  (* x x))

(define (sum-squares lst)
  (apply + (map square lst)))
(define (sum-squares lst)
  (apply + (map (lambda (x) (* x x)) lst)))
甚至更短,作为一个单行程序(但是有一个
square
过程很有用,所以我更喜欢前面的解决方案):

当然,上述任何一种解决方案都能如期发挥作用:

(sum-squares '())
=> 0

(sum-squares '(1 2 3))
=> 14

更实用的方法是将简单函数(
sum
square
)与高阶函数(
map
)结合起来:


我喜欢贝内什的答案,只是稍微修改一下,这样你就不必遍历列表两次。(一次折叠与地图和折叠)

或者您可以只定义map reduce

(define (map-reduce map-f reduce-f nil-value lst)
  (if (null? lst) 
      nil-value
      (map-reduce map-f reduce-f (reduce-f nil-value (map-f (car lst))))))

(define (sum-squares lst) (map-reduce square + 0 lst))  

参数名称应该是
lst
(列表的缩写),而不是
1st
(即“first”),您没有方案解释器吗?或者你没有精力使用它?无论发生什么情况,它都返回“0”失败;你找不到错误?您的第一个猜测是什么?我们是否应该小心应用,因为在某些实现中,它只接受有限数量的参数?@WorBlux或racket不是其中之一?@WorBlux racket没有该限制;)谢谢我还没学会申请,不过还是要谢谢你。我从你的帮助中学到了很多!
(define (square x) (* x x))
(define (square-y-and-addto-x x y) (+  x (square y)))
(define (sum-squares lst) (foldl square-y-and-addto-x 0 lst))
(define (map-reduce map-f reduce-f nil-value lst)
  (if (null? lst) 
      nil-value
      (map-reduce map-f reduce-f (reduce-f nil-value (map-f (car lst))))))

(define (sum-squares lst) (map-reduce square + 0 lst))  
racket@> (define (f xs) (foldl (lambda (x b) (+ (* x x) b)) 0 xs))
racket@> (f '(1 2 3))
14