2016-12-04 67 views
2

我想實現一個遞歸地從給定的流中刪除所有額外空間的函數。任何連續的空格都應該被刪除,從而允許在單詞之間有一個最大空間。我無法弄清楚如何正確實施。球拍計劃 - 從流中刪除重複的連續字符

我已經嘗試將流轉換爲列表並操作它,但我根本無法弄清楚如何構建一個新的流並根據每個元素的測試提供的返回它。我試圖使用流的地圖,但它似乎不爲我在這種情況下工作(刪除元素,構建新的數據流)

這是我目前的破執行刪除,額外空間:

(define remove-extra-spaces 
    (lambda (str) 
    (cond (not (not-more-than-one-space str 0) (stream-append (stream-first str) (remove-extra-spaces (stream-rest str)))) 
      (else (remove-extra-spaces (stream-rest str))) 
     ))) 


    (define not-more-than-one-space 
    (lambda (str count) 
     (cond ((stream-empty? str) #T) 
      ((equal? (stream-first str) #\space) (not-more-than-one-space (stream-rest str) (+ count 1))) 
      ((> count 1) #F) 
      (else #T) 
      ) 
    )) 

我寫了一個測試,以幫助我發現何時有多個連續空格。但是,我無法弄清楚如何使用這個測試來創建一個基於通過它的新流。當我試圖將它與流圖一起使用時,流過濾器不適用於我。

回答

1

你知道如何使用stream-cons?這可能是實現這個最簡單的方法。下面是我實現(採用SRFI 41流庫,而不是racket/stream因爲我更熟悉):

(require srfi/41) 
(define-stream (collapse-spaces strm) 
    (stream-let loop ((was-space #f) 
        (strm strm)) 
    (cond ((stream-null? strm) strm) 
      ((char=? (stream-car strm) #\space) 
      (if was-space 
       (loop #t (stream-cdr strm)) 
       (stream-cons #\space (loop #t (stream-cdr strm))))) 
      (else (stream-cons (stream-car strm) 
          (loop #f (stream-cdr strm))))))) 

採樣運行:

> (stream->list (collapse-spaces (stream #\f #\o #\o #\space #\space #\b #\a #\r))) 
(#\f #\o #\o #\space #\b #\a #\r) 
+0

謝謝。我會考慮使用stream-cons。我將它應用到我的remove-extra-spaces函數中,但是當我嘗試再次將它轉換爲列表時,我會引發錯誤。我用stream-cons替換了stream-append。錯誤是: stream-first:違反合同 預計:(和/ c流?(不/ c流空 - ?)) 給出:#

+0

我應該追求某種內部遞歸,也許與letrec,做這個任務呢?我試圖理解你的實現,所以我也可以自己做。 –

+0

嘗試編寫一個在列表上而不是在流上操作的版本。也就是說,你的函數應該使用一個列表,併產生一個空格摺疊的列表。如果您可以成功寫入,則流版本很容易轉換爲。 –