使用单个函数在不使用驱动程序功能的情况下查找列表中的最小和最大数字?

时间:2015-02-26 03:06:28

标签: list recursion functional-programming scheme

我目前对函数式编程背后的想法感到困惑。我目前有一个解决我的问题的工作解决方案(即找到列表的最小值和最大值,并将它们返回到新列表中)但是为了做到这一点,我的解决方案基本上需要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函数中完成所有这些,但我需要指向正确的方向。谢谢!

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

这实际上是一个非常好的挑战,可能有助于学习一些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))