Printing 在方案中给出一个数字流,我需要打印n个数字,用逗号分隔,如(1,2,3,4,…)

Printing 在方案中给出一个数字流,我需要打印n个数字,用逗号分隔,如(1,2,3,4,…),printing,stream,scheme,Printing,Stream,Scheme,我可以使用下面的代码将n个数字打印为列表: (define (print-first-n stream1 n) (cond((= n 0) '()) (else(cons(stream-car stream1) (print-first-n (stream-cdr stream1) (- n 1)))))) 但是我不知道如何添加逗号。您不能在普通列表中打印逗号,但我们可以用流的内容构建一个字符串,用逗号分隔。假设字符串包含数字,这将起作用: 上述解决方案适用于较小的n,但对于较

我可以使用下面的代码将n个数字打印为列表:

(define (print-first-n stream1 n)
  (cond((= n 0) '())
      (else(cons(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)))))
无论哪种方式:假设
整数
是从
1
开始的无限整数流,它看起来就是这样的:

(print-first-n integers 5)
=> "1, 2, 3, 4, 5"
如果流包含一些其他数据类型,请使用适当的过程将每个元素转换为字符串。

如果您的函数只打印流内容,而不需要构建字符串(如Óscar的答案),那么下面是我对它的看法(使用流):

例如:

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

要输出到字符串(如Óscar的答案),只需将整个内容包装在字符串端口中:

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

是数字->字符串用于将数字从流转换为string@sageArt:没错!如果流包含不同类型的元素,请查找并使用相应的过程将其转换为字符串。@ChrisJester Young fair,我更新了我的答案:)。但是
stringappend
对于初学者来说更容易使用,它是构建字符串时执行自然递归的方法。如果效率是个问题,我同意你的看法。我想知道,使用
(apply string append acc)
是可以的,或者
字符串串联
总是一个更好的选择?@scarLópez
(apply string append acc)
对于接受非常大的
应用列表的方案实现(如Racket、IIRC)来说是不错的
string concatenate
本质上是
string append
使用的内部循环。
> (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)))))