【问题标题】:Using a single function to find min and max numbers in a list without using a driver function?使用单个函数在不使用驱动程序函数的情况下查找列表中的最小和最大数字?
【发布时间】:2015-04-28 07:36:44
【问题描述】:

我目前对一般的函数式编程背后的想法感到困惑。我目前对我的问题有一个可行的解决方案(即找到一个列表的最小值和最大值,并将它们返回到一个新列表中)但是要做到这一点,我的解决方案基本上需要 3 个函数,这让我很困扰,因为我确保有一种方法可以只使用方案中的 1 个函数。

所以.. 我的问题是,如何将 2 个函数的输出组合成 1 个简洁函数? (驱动函数)

这就是我所拥有的......

(define (findMax lst) ; Find and return maximum number in a list
 (cond [(null? lst) '()]
       [(= (length lst) 1) (list-ref lst 0)]
       [(> (list-ref lst 0) (list-ref lst (- (length lst) 1))) (findMax (drop-right lst 1))]
       [(< (list-ref lst 0) (list-ref lst (- (length lst) 1))) (findMax (cdr lst))]
       (else
        (findMax (cdr lst))
        )
       )
  )

(define (findMin lst) ; Find and return smallest number in a list
 (cond [(null? lst) '()]
       [(= (length lst) 1) (list-ref lst 0)]
       [(> (list-ref lst 0) (list-ref lst (- (length lst) 1))) (findMin (cdr lst))]
       [(< (list-ref lst 0) (list-ref lst (- (length lst) 1))) (findMin (drop-right lst 1))]
       (else
        (findMin (cdr lst))
        )
       )
  )

我使用驱动函数来获取这两个函数,并在此处显示一个新列表:

(define (findEnds lst)
  (list (findMin lst) (findMax lst))
  )

所以本质上,如果给定一个列表:

(6 7 8 4 9 2)

输出将是:

(2 9)

我知道有一些方法可以使用 lambda 可能在 1 个函数中完成所有这些,但我需要指出正确的方向。谢谢!

【问题讨论】:

    标签: list recursion functional-programming scheme


    【解决方案1】:

    这是我的版本(请注意,我已将其更改为将结果作为单个点对返回,而不是包含两个元素的列表):

    (define (min/max lst)
      (if (empty? lst)
          #f
          (let ((next (min/max (cdr lst))))
            (define cur (car lst))
            (if (not next)
                (cons cur cur)
                (cons (min (car next) cur) (max (cdr next) cur))))))
    

    例子:

    > (min/max '(3 1 4 1 5 9))
    (1 . 9)
    

    † 如果您真的想使用两个元素的列表,请将所有cons 更改为list,并将(cdr next) 更改为(cadr next)

    【讨论】:

    • 我对@9​​87654327@ 的使用只是定义了一个保存递归结果的局部变量(您不想多次递归同一个子列表!)。第一个if 用于处理基本情况(返回#f,如果没有剩余元素,则返回false 值),第二个if 用于处理从递归返回的#f。祝你学习代码好运!
    【解决方案2】:

    这实际上是一个非常好的挑战,可能有助于学习一些 Scheme 概念。我已经使用fold-left 实现了min/max。使用named-let 也可能很有趣

    (define (min/max lst)      
      (fold-left 
        (lambda (acc num)
          (cons (min num (car acc)) (max num (cdr acc))))
        (cons +inf.0 -inf.0)
        lst))
    

    【讨论】:

    • 我不建议使用(cons +inf.0 -inf.0) 作为初始值。如果有的话,请使用#f(与我的解决方案类似)。这是因为使用不精确的数字 +inf.0-inf.0 会强制调用 minmax 的结果也不精确。
    • 嗯我也想过,但是显然不能说(min #f num),所以我偷懒就选了+inf.0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多