我可以低於該代碼打印正數作爲列表:給數字流在方案我需要打印N乘逗號分隔的數字像(1,2,3,4,...)
(define (print-first-n stream1 n)
(cond((= n 0) '())
(else(cons(stream-car stream1) (print-first-n (stream-cdr stream1) (- n 1))))))
但我不知道如何添加逗號。
我可以低於該代碼打印正數作爲列表:給數字流在方案我需要打印N乘逗號分隔的數字像(1,2,3,4,...)
(define (print-first-n stream1 n)
(cond((= n 0) '())
(else(cons(stream-car stream1) (print-first-n (stream-cdr stream1) (- n 1))))))
但我不知道如何添加逗號。
不能在普通列表中打印逗號,但我們可以用流的內容構建一個字符串,用逗號分隔。這將工作,假設該字符串包含數字:
(define (print-first-n stream1 n)
(cond ((= n 1)
(number->string (stream-car stream1)))
(else
(string-append
(number->string (stream-car stream1)) ", "
(print-first-n (stream-cdr stream1) (- n 1))))))
上述解決辦法是罰款的n
一個很小的值,而是非常低效的大值(大量的臨時字符串將被創建,與O(n^2)
複雜爲追加操作)。爲了更有效的實現,可以考慮使用SRFI-13的串聯程序,就像這樣:
(require srfi/13)
(define (print-first-n stream1 n)
(let loop ((strm stream1) (n n) (acc '()))
(if (= n 1)
(string-concatenate-reverse
(cons (number->string (stream-car strm)) acc))
(loop (stream-cdr strm)
(sub1 n)
(list* ", " (number->string (stream-car strm)) acc)))))
無論哪種方式:讓我們說integers
是起始於1
整數的無限流,這是它會怎樣看:
(print-first-n integers 5)
=> "1, 2, 3, 4, 5"
如果流包含其他某種數據類型,請使用適當的過程將每個元素轉換爲字符串。
如果功能只是打印流內容,並不需要建立一個字符串(如奧斯卡的答案),這是我對其採取(使用SRFI 41流):
(define (print-first-n stream n)
(stream-for-each (lambda (delim item)
(display delim)
(display item))
(stream-cons "" (stream-constant ", "))
(stream-take n stream)))
例子:
> (define natural (stream-cons 1 (stream-map (lambda (x) (+ x 1)) natural)))
> (print-first-n natural 10)
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
輸出到一個字符串(如奧斯卡的答案),只是包裝在一個字符串端口整個事情:
(define (print-first-n stream n)
(call-with-output-string
(lambda (out)
(stream-for-each (lambda (delim item)
(display delim out)
(display item out))
(stream-cons "" (stream-constant ", "))
(stream-take n stream)))))
是那個數字 - >字符串是用於將數字轉換爲字符串到字符串 – sageArt
@sageArt:沒錯!如果您的流包含不同類型的元素,請查找並使用相應的過程將其轉換爲字符串。 –
@ ChrisJester-Young夠公平的,我更新了我的答案:)。但'string-append'對於初學者來說更容易使用,它是構建字符串時自然遞歸的方式。如果效率問題,我同意你的看法。我想知道,使用'(apply string-append acc)'會沒問題,或者'string-concatenate'總是更好的選擇? –