Scheme,级别中级学生,找不到递归的min

时间:2013-12-01 02:51:05

标签: scheme racket

如何使用抽象列表函数(foldr,map和filter)编写函数而不使用消耗数字列表的递归(列出a1 a2 a3 ...)并生成一个新列表,从原始列表中删除最小数字列出?

递归代码是:

(define (find-min lst)
  (cond
    [(empty? (rest lst)) (first lst)]
    [else
     (local [(define min-rest (find-min (rest lst)))]
       (cond
         [(< (first lst) min-rest) (first lst)]
         [else min-rest]))]))

3 个答案:

答案 0 :(得分:2)

折叠对给定值应用2参数函数,列表的汽车对连续的汽车或cdrs或列表使用结果。这就是我们想要的。

而map通过对列表的每个元素执行某些操作来返回新列表。

过滤器根据某个谓词返回一个更小或相等的列表。

现在只需要制定一个可以选择两个参数的出租人的函数

(define (the-lessor x y)
 (if (< x  y)
     x
     y))

从那里实施很简单。

(define (min L) (fold the-lessor (car L) (cdr L)))

答案 1 :(得分:1)

由于这看起来像是一个家庭作业问题,我不打算提供所有代码,但希望能帮助你朝着正确的方向前进。

HTDP book,我们看到“中级学生语言添加了本地绑定和高阶函数。”这里的诀窍可能是使用“本地绑定”。

一些假设:

  • (remove-min-from-list '()) => not allowed: input list must be non-empty
  • (remove-min-from-list '(1)) => '()
  • (remove-min-from-list '(1 2 3 1 2 3)) => '(2 3 2 3) ; all instances of 1 were removed

不知何故,我们需要找到列表的最小值。调用此函数min-of-list。它的输入和输出是什么?它的输入是一个数字列表,其输出是一个数字。在抽象列表函数中,哪些允许我们将数字列表转换为数字? (而不是其他列表。)这对我来说就像foldl / foldr

(define (min-of-list lst)
    (foldr some-function some-base lst))

既然你已经证明你可以递归地写min-of-list,那就让我们继续吧。请参阅@ WorBlux的答案以获取提示。

我们如何在下一个函数remove-min-from-list中使用它? remove-min-from-list的输入和输出是什么?它需要一个数字列表并返回一个数字列表。好的,看起来像mapfilter。但是,输入列表可能比输出列表短,因此filter而不是map

(define (remove-min-from-list lst)
    ....
    (filter some-predicate list))

some-predicate看起来像什么?它需要返回#f作为列表的最小值。

让我们将它们全部拉到一起并使用local编写一个函数:

(define (remove-min-from-list lst)
  (local [(define min-value ...)
          (define (should-stay-in-list? number) ...min-value ...)]
    (filter should-stay-in-list? lst)))

此处的关键是,should-stay-in-list?的定义可以引用min-value,因为min-value位于local定义块之前filter should-stay-in-list?稍后可以使用local因为它位于{{1}}。

的正文中

答案 2 :(得分:-2)

(define (comparator n) (local [(define (compare v) (not (equal? v n)))] compare))
(define (without-min list) (filter (comparator (foldr min (foldr max 0 list) list)) list))