有没有人知道在方案中解释抽象列表功能的任何好问题或网站?出于某种原因,我很难理解抽象列表函数以及如何使用它们。
当给出一个必须单独使用抽象列表函数解决的问题时,我几乎完全迷失了。
作为一个例子,我如何编写一个只使用抽象列表函数查找列表中最大元素的函数?
这是我到目前为止所做的:
(define (maximum lst)
(foldr (lambda (e acc) (if (empty? acc) empty
(if (< acc e) acc empty))) empty lst))
有人可以向我解释为什么它不起作用以及我做错了什么? 非常感谢
答案 0 :(得分:2)
(请注意,我假设您使用了Racket,因为您的代码中的参数顺序为foldr
;如果我对此错误,我可以将其调整为。) < / p>
我会这样做:
(define (maximum lst)
(if (null? lst)
lst
(foldl
(lambda (e r) (if (< r e) e r)) ; function to call successively
(car lst) ; initial value for the result r
(cdr lst)))) ; list to call function for (element by element)
car
,如果列表为空则会抛出错误)foldl
(为此,如果您使用foldl
或foldr
无效,但foldl
效率更高)
car
)cdr
),使用1.下一个元素调用该函数2.前一个结果foldl
的结果)示例:
(maximum '(3 6 7 1))
car lst
)foldl
的结果请注意,Racket有第二种表达方式,可能更容易阅读,因为它更接近传统的for循环:
(define (maximum lst)
(if (null? lst)
'()
(for/fold ((r (car lst))) ((e (in-list (cdr lst))))
(if (< r e) e r))))
答案 1 :(得分:0)
当你寻求帮助时,要理解为什么它不起作用。
(define (maximum lst)
(foldr (lambda (e acc) (if (empty? acc) empty
(if (< acc e) acc empty))) empty lst))
这里的问题是你的初始对象是“空的”。这意味着acc
开头时fold
为空。在英语中,您的代码将按如下方式编写:
以lst
折叠,从空开始。如果acc
为空,则返回空。否则,acc
小于e
返回e
但如果不是,请返回空。返回的值将成为新的acc
。
这里有两个问题:当你从空开始时:acc总是空的。另一个问题是:
(if (< acc e) acc empty)
在这里,如果它小于e
,你将返回acc,否则你将返回空。但如果acc
小于e
,则意味着e更大。这意味着您应该返回e
而不是empty
。
没有真正的理由来检查你的折叠中的empty?
。
折叠电话看起来像这样:
(foldr (lambda (e acc) (if (< acc e) e acc)) (car lst) (cdr lst))
其转换为折叠列表其余部分的第一个元素。如果acc小于e则返回e,否则返回acc。返回的值将在下一次迭代中替换acc。
不需要做的就是检查空列表,你可能会看到类似的内容。
(define (maximum lst)
(if (empty? lst)
(error "Cannot find max from empty list")
(foldr
(lambda (e acc)
(if (< acc e) e acc))
(car lst)
lst)))
还有一件事,foldl
和foldr
是相同的,除了一个从第一个元素开始,一个从最后一个元素开始。在我的解决方案中,我没有测试,但由于我的最后一个参数是整个列表,所以你使用的折叠版本无关紧要。