【问题标题】:How do I scale values all the values in a list where the largest value is 1 and the smallest value is 0如何缩放列表中最大值为 1 且最小值为 0 的所有值的值
【发布时间】:2019-12-08 08:36:38
【问题描述】:

我正在尝试缩放列表中的所有值,其中最大值为 1,最小值为 0。这是我尝试完成的示例

(check-expect (squash (list 100 90 70 20)) (list 1 0.875 0.625 0)).

如您所见,最大值为 100,因此缩放值为 1,最小值为 20 被缩小为 0。

为了缩小所有这些值,我正在执行计算 Z=(Li - (smallest-val)) / ((largest-val) - (smallest-val))

其中 Li 是列表中的所有值 (L1, L2, L3 ...)

这是我目前的代码

(define (squash L)
  (local
    [
     ;;(largest-val M) returns the largest value M in L
     ;;(largest-val: (listof Num) -> Num
     (define (largest-val M) (foldr max (first M) (rest M)))

     ;;(smallest-val x) returns the smallest value x in L
     ;;(smallest-val: (listof Num) -> Num
     (define (smallest-val x) (foldr min (first x) (rest x)))
     ]
    (cond
      [(empty? L)'()]
      [else (cons (/ (- (first L) smallest-val) (- largest-val smallest-val))
                   (squash (rest L)))])))

这是我遇到的错误

:: -: 需要一个数字作为第二个参数,给定 (lambda (a1) ...)

我不确定如何修复此代码以使我的程序正常运行

我想使用命令式编程范例来保留我的解决方案,因此我希望我的答案保持与现在相同的格式。

【问题讨论】:

  • 抱歉,我似乎忘记在(第一个 L)之前添加“-”符号,我会查看我的问题并编辑我的问题。

标签: scheme racket imperative


【解决方案1】:

local 内部,您将largest-valsmallest-val 定义为过程,但在squash 的实际主体中,您没有调用他们,而不是你使用它们,就好像它们是数字一样;这就是-: expects a number as 2nd argument, given (lambda (a1) ...) 错误的含义。

不过,还有一个更严重的问题。您似乎打算在每次迭代时计算最小值和最大值,但这会产生不正确的结果。您必须只计算这些值一次 - 如果我们定义一个帮助程序会更容易,如下所示:

(define (squash L)
  (squash-helper L (apply min L) (apply max L)))

(define (squash-helper L minL maxL)
  (cond [(empty? L) '()]
        [else (cons (exact->inexact (/ (- (first L) minL) (- maxL minL)))
                    (squash-helper (rest L) minL maxL))]))

我使用exact->inexact 来去除分数,还有一种更简单的方法可以使用apply 以及minmax 来查找列表的最小值和最大值。现在程序按预期工作:

(squash (list 100 90 70 20))
=> '(1.0 0.875 0.625 0.0)

【讨论】:

    【解决方案2】:

    这是你的函数的一个变体:

    (define (squash L)
      (local
        [
         ;;(largest-val M) returns the largest value M in L
         ;;(largest-val: (listof Num) -> Num
         (define (largest-val M) (foldr max (first M) (rest M)))
    
         ;;(smallest-val x) returns the smallest value x in L
         ;;(smallest-val: (listof Num) -> Num
         (define (smallest-val x) (foldr min (first x) (rest x)))
         (define (scale x)
           (/ (- x                 (smallest-val L))
              (- (largest-val  L)  (smallest-val L))))]
        (map scale L)))
    

    函数map 将函数scale 应用于列表L 的每个元素,并返回一个包含所有结果的新列表。

    【讨论】:

    • 我有一个关于代码的问题,代码是否只计算列表 L 中的每个值一次。我不希望列表中的任何值被计算多次。我相当有信心这段代码没有这样做,但我只想确保我的假设是正确的,不管答案很好,我只是想更好地理解 Racket 的命令式编程
    • 是的。只有一次。
    • 但是每次调用 scale 时都会计算最小值和最大值。因此,您可以先计算它们(在本地定义中),然后在比例定义中使用它们。
    • 如何将这些值存储为常量,但我将代码更改为 (define maximum-val (foldr max (first L) (rest L))) 和 (define minimum-val (foldr min (first L) (rest L))) 和 (define (scale t) (/ (- t (smallest-val)) (- (largest-val) (smallest-val)))) 并且代码不起作用所以我想知道是否必须更改最大val和最小val代码的定义
    • 我应该提到我使用第一个示例收到的错误是函数调用:期望在左括号后有一个函数,但收到 20
    猜你喜欢
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    相关资源
    最近更新 更多