给出一个数字流,我需要打印n个以逗号分隔的数字,如(1,2,3,4,.)



我可以用下面的代码打印n个数字:

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

如果流包含其他数据类型,使用适当的过程将每个元素转换为字符串。

如果您的函数只是打印流内容,并且不需要构建字符串(如Óscar的答案),下面是我的看法(使用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

要输出到字符串(如Ó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)))))

相关内容

  • 没有找到相关文章

最新更新