目前我有
(define filter
(λ (f xs)
(letrec [(filter-tail
(λ (f xs x)
(if (empty? xs)
x
(filter-tail f (rest xs)
(if (f (first xs))
(cons (first xs) x)
'()
)))))]
(filter-tail f xs '() ))))
它应该具有过滤功能
但输出为
(filter positive? '(-1 2 3))
>> (3 2)
但正确的回报应为(2 3)
我想知道代码是否使用尾递归正确完成,如果是,那么我应该使用反向来改变答案?
答案 0 :(得分:2)
我想知道代码是否使用尾递归正确完成。
是的,它正在使用正确的尾调用。
(define (filter-tail f xs x) ...)
其中,内部以递归方式应用于
(filter-tail f
(some-change-to xs)
(some-other-change-to x))
并且,从外部它应用于
(filter-tail f xs '())
这两个应用程序都处于尾部位置
我应该用反向来改变答案吗?
是的,除非你在构建它时改变列表的尾部(而不是预先设置一个头),否则它无法绕过它。您收到的其中一条评论是使用set-cdr!
提到的(另请参阅: Getting rid of set-car! and set-cdr! )。可能还有其他技术,但我不知道它们。我很乐意听到他们的声音。
这是尾递归,需要反转输出。这个使用名为let。
(define (filter f xs)
(let loop ([ys '()]
[xs xs])
(cond [(empty? xs) (reverse ys)]
[(f (car xs)) (loop (cons (car xs) ys) (cdr xs))]
[else (loop ys (cdr xs))])))
(filter positive? '(-1 2 3)) ;=> '(2 3)
这是另一个使用左折叠的人。输出仍然需要反转。
(define (filter f xs)
(reverse (foldl (λ (x ys) (if (f x) (cons x ys) ys))
'()
xs)))
(filter positive? '(-1 2 3)) ;=> '(2 3)
答案 1 :(得分:0)
使用"difference-lists"技术和curried functions,我们can have
(define (fold c z xs)
(cond ((null? xs) z)
(else (fold c (c (car xs) z) (cdr xs)))))
(define (comp f g) (lambda (x) ; ((comp f g) x)
(f (g x))))
(define (cons1 x) (lambda (y) ; ((cons1 x) y)
(cons x y)))
(define (filter p xs)
((fold (lambda (x k)
(if (p x)
(comp k (cons1 x)) ; nesting's on the left
k))
(lambda (x) x) ; the initial continuation, IC
xs)
'()))
(display (filter (lambda (x) (not (zero? (remainder x 2)))) (list 1 2 3 4 5)))
这构建
comp
/ \
comp cons1 5
/ \
comp cons1 3
/ \
IC cons1 1
并对其应用'()
,以高效的从右向左顺序构建结果列表,因此无需撤消它。
首先,fold
通过逐个组合consing函数以尾递归方式构建结果列表的差异列表表示;然后,结果函数应用于'()
并再次以尾递归的方式通过comp
函数组合定义的优点减少,因为组合函数在左侧嵌套 ,因为fold
是左折叠,处理列表从左到右:
( (((IC+k1)+k3)+k5) '() ) ; writing `+` for `comp`
=> ( ((IC+k1)+k3) (k5 '()) ) ; and `kI` for the result of `(cons1 I)`
<= ( ((IC+k1)+k3) l5 ) ; l5 = (list 5)
=> ( (IC+k1) (k3 l5) )
<= ( (IC+k1) l3 ) ; l3 = (cons 3 l5)
=> ( IC (k1 l3) )
<= ( IC l1 ) ; l1 = (cons 1 l3)
<= l1
由fold
构建的函数的大小为 O(n),就像临时列表所具有的那样,具有反转。