2012-04-24 52 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'的用法? – 2012-04-24 02:32:57

+0

我也不確定,但我想這是與在原始輸入列表中改變指針相關的東西,它使濾鏡和ints1等效。這是最讓我困惑的。 – 2012-04-24 03:09:51

+0

可能的重複[做一個破壞性的反向!函數在方案](http://stackoverflow.com/questions/10266086/make-a-destructive-reverse-function-in-scheme) – matt 2012-04-24 03:33:37

回答

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

我改編自filter!過程中的上述SRFI 1:列表庫。請注意,如果您使用的是Racket,則需要修改上述代碼才能正常工作。例如,球拍不再支持set-cdr!,您必須改用set-mcdr!