List 完全根的拍和实现

List 完全根的拍和实现,list,scheme,racket,List,Scheme,Racket,我正在尝试编写一个Racket函数,它接受一系列数字作为输入,并输出这些数字的平方根之和,这些数字都是完美的平方。我目前没有编译的代码如下: (define (sum-of-perfect-roots lst) (apply + (map (lambda (number) (sqrt number)) (filter (exact? sqrt(number)) lst)))) 我知道我的错误在于对filter函数使用谓词。我不知道如何正确返回只有完美正方

我正在尝试编写一个Racket函数,它接受一系列数字作为输入,并输出这些数字的平方根之和,这些数字都是完美的平方。我目前没有编译的代码如下:

(define (sum-of-perfect-roots lst)
  (apply + (map (lambda (number)
                  (sqrt number)) (filter (exact? sqrt(number)) lst))))

我知道我的错误在于对filter函数使用谓词。我不知道如何正确返回只有完美正方形的列表。感谢您的帮助

Racket实际上有一个内置的数学库,数学/数论模块提供了一个方便的工具。perfect square的文档描述如下:

(define (sum-of-perfect-roots lst)
  (apply + (map (lambda (number)
                  (sqrt number)) (filter (exact? sqrt(number)) lst))))
如果m是完全平方,则返回sqrt m,否则返回f

当然,这使得实现您的函数变得微不足道。你可以这样做:

(require math/number-theory)

(define (sum-of-perfect-roots lst)
  (apply + (filter-map perfect-square lst)))
使用过滤器映射也更有效,因为它不需要构建两次列表。尽管如此,如果您愿意为了学习目的而推出自己的实现,那么重新实现perfect square也不会非常困难

(define (perfect-square n)
  (define root (sqrt n))
  (if (integer? root) root #f))
如果您想让它更高效,可以避免完全使用fold构建中间列表。Racket的for/sum理解表单使这一点易于实现

(define (sum-of-perfect-roots lst)
  (for/sum ([n (in-list lst)])
    (or (perfect-square n) 0)))

您还可以使用整数sqrt/余数:定义完美平方n定义值q r整数sqrt/余数n和零?r q。另外,对于您的for版本的完美根之和,在本例中,只使用for/sum而不是for/fold更容易。@ChrisJester Young感谢for/sum点-我总是忘记它的存在是出于某种原因。无论如何,我编辑的注释包括一个整数sqrt/余数版本的完美平方:-如果可以避免的话,我会尽量避免浮点数,但这只是我的问题。@ChrisJester-Young-sqrt的输入是精确的,输出是有理的,则它是精确的,但整数sqrt可能更快。此外,您还可以在列表中的*/sum n中使用lst r的值完美平方n:when r r。价值观提供了类似于理解的东西-