这是我的代码:
(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]的列表,我需要对每个数字求平方并将它们加在一起,输出 - 数字。 如果输入了正确的答案,测试将返回#t。
答案 0 :(得分:4)
这与您的previous question非常相似,但有一个转折:这里我们添加,而不是相乘。每个元素在添加之前都会被平方:
(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)))))
您必须意识到两个解决方案共享相同的结构,所做的更改是:
+
合并答案,而不是*
(first lst)
0
(乘法为1
)作为最终评论,在实际应用中你不应该使用显式递归,而是使用高阶程序来编写我们的解决方案:
(define (square x)
(* x x))
(define (sum-squares lst)
(apply + (map square lst)))
甚至更短,作为一个单行(但是对square
程序有用,所以我更喜欢以前的解决方案):
(define (sum-squares lst)
(apply + (map (lambda (x) (* x x)) lst)))
当然,上述任何解决方案都可以按预期运行:
(sum-squares '())
=> 0
(sum-squares '(1 2 3))
=> 14
答案 1 :(得分:4)
更实用的方法是将简单函数(sum
和square
)与高阶函数(map
)结合起来:
(define (square x) (* x x))
(define (sum lst) (foldl + 0 lst))
(define (sum-squares lst)
(sum (map square lst)))
答案 2 :(得分:0)
我喜欢Benesh的答案,只是略微修改它,所以你不必两次遍历列表。 (与地图折叠一次并折叠)
(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))
或者你可以定义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))
答案 3 :(得分:0)
racket@> (define (f xs) (foldl (lambda (x b) (+ (* x x) b)) 0 xs))
racket@> (f '(1 2 3))
14