2012-11-11 71 views
1

我有這個方案過程,該過程使謂詞爲真的(嵌套)列表中的所有東西都成爲列表。如何在方案中製作深度過濾器

(define (deep-filter f lst) 
(cond 
    ((null? lst) '()) 
    ((and (atom? lst) (f lst)) lst) 
    ((atom? lst) '()) 
    (else (cons (deep-filter f (car lst)) 
       (deep-filter f (cdr lst)))))) 

一個例子:

(deep-filter number? '(2 (a ((c)) (1)) 6)) => (2 (() ((())) (1)) 6) 

是否有可能解決這個問題的過程,以便它不打印空列表?

在此先感謝

回答

2

試試這個:

(define (deep-filter f lst) 
    (cond 
    ((null? lst) '()) 
    ((and (atom? lst) (f lst)) (list lst)) 
    ((atom? lst) '()) 
    (else (append (deep-filter f (car lst)) 
        (deep-filter f (cdr lst)))))) 

這就是所謂的平整列表,訣竅是使用append代替cons和裝箱單元素(cond秒情況下)內的名單。請注意,這將消除所有子列表,只返回滿足謂詞的元素。

如果您需要刪除空列表後保存表結構,然後做這個:

(define (deep-filter f lst) 
    (cond ((null? lst) 
     '()) 
     ((atom? (car lst)) 
     (if (f (car lst)) 
      (cons (car lst) (deep-filter f (cdr lst))) 
      (deep-filter f (cdr lst)))) 
     (else 
     (filter (compose not null?) 
       (cons (deep-filter f (car lst)) 
         (deep-filter f (cdr lst))))))) 

現在它將會按預期:

(deep-filter number? '(2 (a ((c)) (b)) 6)) 
=> '(2 6) 

(deep-filter number? '(2 (a ((c)) (1)) 6)) 
=>'(2 ((1)) 6) 

(deep-filter number? '(2 (a ((4)) (1)) 6)) 
=> '(2 (((4)) (1)) 6) 

(deep-filter number? '(2 (a ((4)) (1)) 6 ((((((b)))))))) 
=> '(2 (((4)) (1)) 6) 
+0

是啊,我明白了,但不幸的是我需要事物(例子中的數字)留在原來的位置(如果他們在一箇中,他們必須留在嵌套列表中)。謂詞錯誤的事物必須被刪除,以及他們所在的列表... –

+0

@Neyuh我明白了。對於問題中的例子,預期的輸出是什麼? –

+0

'(2(a((c))(1))6))=>(2((1))6)) –