2

述語が真である (ネストされた) リスト内のすべてのもののリストを作成するこのスキーム手順があります。

(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)

空のリストを出力しないようにこの手順を修正することは可能ですか?

前もって感謝します

4

1 に答える 1

3

これを試して:

(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))))))

これはリストの平坦化と呼ばれ、リスト内の単一の要素 ( の 2 番目のケース) のappend代わりに使用してパックするというトリックです。これにより、すべてのサブリストが削除され、述語を満たす要素のみが返されることに注意してください。conscond

空のリストを削除した後にリスト構造を保持する必要がある場合は、代わりに次のようにします。

(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)
于 2012-11-11T17:11:56.847 に答える