如何使用抽象列表函数(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]))]))
答案 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
的输入和输出是什么?它需要一个数字列表并返回一个数字列表。好的,看起来像map
或filter
。但是,输入列表可能比输出列表短,因此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))