我知道如何以递归方式编写它。
(define (removed2 lst)
(cond
[(empty? lst) empty]
[(not (member? (first lst) (rest lst)))
(cons (first lst) (removed2 (rest lst)))]
[else (removed2 (rest lst))]))
so(removed2(list 1 1 1 2 2 2 3 3 3 3 3 3))给出(list 1 2 3)
但是,如何仅使用抽象函数(filter,foldr,map和build-list)重写它?
我尝试使用过滤器,但它不起作用。
答案 0 :(得分:2)
为此可以使用foldr
,诀窍是知道在lambda
中写什么:
(define (removed lst)
(foldr (lambda (e a)
(if (not (member? e a))
(cons e a)
a))
'()
lst))
同时检查您的口译员是否具有内置功能,例如在Racket中您可以使用remove-duplicates
。
答案 1 :(得分:2)
过滤强>
仅限于踢,filter
的版本:
(define (make-unique-filter)
(let ((seen '()))
(lambda (e)
(if (member e seen)
#f
(begin
(set! seen (cons e seen))
#t)))))
(define (removed2 lst)
(filter (make-unique-filter) lst))
然后
(removed2 (list 1 1 1 2 2 2 3 3 3 3 3 3))
=> '(1 2 3)
(removed2 (list 1 2 3 1 2 3 1 2 3 1 2 3))
=> '(1 2 3)
<强> FOLD 强>
但当然, fold 是要走的路。但是,通常最好使用左侧折叠(至少在Racket中,请参阅here),但结果必须颠倒过来:
(define (removed2 lst)
(reverse
(foldl
(lambda (e a)
(if (not (member e a))
(cons e a)
a))
'()
lst)))
或纯粹的方案:
(define (removed2 lst)
(reverse
(fold-left
(lambda (a e)
(if (not (member e a))
(cons e a)
a))
'()
lst)))