2012-04-24 6 views
1

私はフィルターの作品を得ることができますが、それは破壊的にそれをしません。以下は、起動コードとテストケースです:破壊フィルターの作成方法スキームで?

(define (filter! f s) 
;;Your solution 

テストケース:

(define (big x) (> x 5)) 

(define ints (list 1 10 3 8 4 7)) 
(define ints1 (cdr ints)) 


(define filtered-ints (filter! big ints)) 
filtered-ints 
; expect (10 8 7) 

(eq? filtered-ints ints1) ; expect #t 

誰も助けてくださいもらえますか?

+0

あなたは、テストに合格しなかった要素を削除することによって、フィルタが引数として与えられたリストを変更することを意味しますか?ここで 'ints1'の使用は何ですか? –

+0

どちらか分かりませんが、元の入力リストでポインタが変更され、filtered-intsとints1を同等にすることに関連していると思います。それが私を最も混乱させるものです。 –

+0

可能な複製[破壊的な逆を作る! function in scheme](@stackoverflow.com/questions/10266086/make-a-destructive-reverse-function-in-scheme) – matt

答えて

1

これは動作するはずです:リストライブラリ:

(define (filter! f lst) 
    (let loop ((ans lst)) 
    (cond ((null? ans) 
      ans) 
      ((not (f (car ans))) 
      (loop (cdr ans))) 
      (else 
      (scan-in f ans (cdr ans)) 
      ans)))) 

(define (scan-in f prev lst) 
    (if (pair? lst) 
    (if (f (car lst)) 
     (scan-in f lst (cdr lst)) 
     (scan-out f prev (cdr lst))))) 

(define (scan-out f prev lst) 
    (let loop ((lst lst)) 
    (if (pair? lst) 
     (if (f (car lst)) 
      (begin (set-cdr! prev lst) 
        (scan-in f lst (cdr lst))) 
      (loop (cdr lst))) 
     (set-cdr! prev lst)))) 

を私はSRFI 1でfilter!手順から上記適応。ラケットを使用している場合、上記のコードが正しく動作するためには、1つまたは2つの修正が必要であることに注意してください。たとえば、Racketはset-cdr!をサポートしていないため、代わりにset-mcdr!を使用する必要があります。