如何在RACKET中做广场

时间:2014-03-21 13:46:07

标签: 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]的列表,我需要对每个数字求平方并将它们加在一起,输出 - 数字。 如果输入了正确的答案,测试将返回#t。

4 个答案:

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

更实用的方法是将简单函数(sumsquare)与高阶函数(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