使用方案功能需要帮助
返回一个列表,其中包含满足给定谓词的给定列表的所有元素。例如,(filter (lambda (x) (< x 5)) '(3 9 5 8 2 4 7))
应返回(3 2 4)
。
答案 0 :(得分:6)
filterb - 以防万一已经有一个名为filter的函数。
(define filterb
(lambda (pred lst)
(cond ((null? lst) '())
((pred (car lst)) (cons (car lst) (filterb pred (cdr lst))))
(else (filterb pred (cdr lst))))))
虽然我确信它可以看起来更好。
答案 1 :(得分:4)
编写filter
过程的简单方法:
(define (my-filter pred lst)
(cond ((null? lst) null)
((pred (first lst))
(cons (first lst) (my-filter pred (rest lst))))
(else (my-filter pred (rest lst)))))
请注意,我将过程命名为my-filter
,因为已经存在一个名为filter
的内置过程,并且覆盖其定义不是一个好主意。
答案 2 :(得分:1)
过滤器的教科书定义是其他海报所展示的(非尾部)递归 - 并且理解那个是很重要的。但是,如果你把它写成库函数,那么弄清楚如何使用尾递归来做这件事很有用,这样你就不会用长列表炸掉堆栈或堆:
(define (filter pred? list)
(define (filter-aux result current-pair xs)
(cond ((null? xs)
result)
((pred? (car xs))
(set-cdr! current-pair
(cons (car xs)
'()))
(filter-aux result
(cdr current-pair)
(cdr xs)))
(else
(filter-aux result
current-pair
(cdr xs)))))
(let ((init (cons 'throw-me-out '())))
(filter-aux (cdr init) init list)))
或者,使用let loop
语法:
(define (filter pred? xs)
(let ((result (cons 'throw-me-out '()))
(xs xs))
(let loop ((current-pair result))
(cond ((null? xs)
(cdr result))
((pred? (car xs))
(set-cdr! current-pair
(cons (car xs) '()))
(loop (cdr current-pair) (cdr xs)))
(else
(loop current-pair (cdr xs)))))))
答案 3 :(得分:0)
尝试将filter
定义为fold-right的实例:
(define (my-filter op xs)
(fold-right
(lambda (next result) ...)
'()
xs))
提示:使用if
和cons
答案 4 :(得分:0)
对于不需要可变列表的备用尾递归filter
,您可以使用以下内容:
(define (my-filter f lst)
(define (iter lst result)
(cond
((null? lst) (reverse result))
((f (car lst)) (iter (cdr lst)
(cons (car lst) result)))
(else (iter (cdr lst)
result))))
(iter lst '()))
反向要求你第二次遍历列表,但是它可以在O(n)时间内实现,并且在不可变列表上有不断的堆栈空间,所以整个时间仍然是O(n)。