【问题标题】:Racket Sum of Perfect Roots Implementation完美根实现的球拍总和
【发布时间】:2015-02-17 15:53:51
【问题描述】:

我正在尝试编写一个 Racket 函数,该函数将数字列表作为输入,并输出列表中完美平方数的平方根之和。我的代码目前没有编译,如下:

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

我知道我的错误在于过滤函数的谓词的使用。我不知道如何正确返回仅完美正方形的列表。任何帮助表示赞赏!

【问题讨论】:

    标签: list scheme racket


    【解决方案1】:

    Racket 实际上有一个内置的数学库,math/number-theory 模块提供了一个方便的perfect-square functionperfect-square 的文档描述如下:

    如果m 是完美正方形,则返回(sqrt m),否则返回#f

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

    (require math/number-theory)
    
    (define (sum-of-perfect-roots lst)
      (apply + (filter-map perfect-square lst)))
    

    使用filter-map 也更有效,因为它不需要构建列表两次。不过,如果您更愿意出于学习目的推出自己的实现,那么重新实现 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)))
    

    【讨论】:

    • 你也可以使用integer-sqrt/remainder:(define (perfect-square n) (define-values (q r) (integer-sqrt/remainder n)) (and (zero? r) q))。此外,对于您的for 版本的sum-of-perfect-roots,在这种情况下,使用for/sum 而不是for/fold 会更容易。
    • @ChrisJester-Young 感谢for/sum 点——我总是因为某种原因忘记它的存在。
    • 无论如何,我编辑的评论包括integer-sqrt/remainder 版本的perfect-square。 :-D(如果可以避免,我会尽量避免浮点,但这只是我。)
    • @ChrisJester-Young sqrt 如果输入准确且输出合理则准确,但integer-sqrt 可能更快。
    • 另外,您可以使用(for*/sum ((n (in-list lst)) (r (in-value (perfect-square n))) #:when r) r)in-value 在理解中提供类似于 let 的东西。 :-)
    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 2018-09-23
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    相关资源
    最近更新 更多