【问题标题】:How to append two streams?如何附加两个流?
【发布时间】:2015-05-31 19:28:32
【问题描述】:

我有这些功能

(define force!
  (lambda (thunk)
    (thunk)))


(define stream-head
  (lambda (s n)
    (if (zero? n)
        '()
        (cons (car s)
              (stream-head (force! (cdr s))
                           (1- n))))))

(define make-stream
  (lambda (seed next)
    (letrec ([produce (lambda (current)
                        (cons current
                              (lambda ()
                                (produce (next current)))))])
      (produce seed))))



(define make-traced-stream
  (lambda (seed next)
    (letrec ([produce (trace-lambda produce (current)
                        (cons current
                              (lambda ()
                                (produce (next current)))))])
      (produce seed))))

(define stream-of-even-natural-numbers
  (make-traced-stream 0
                      (lambda (n)
                        (+ n 2))))

(define stream-of-odd-natural-numbers
  (make-traced-stream 1
                      (lambda (n)
                        (+ n 2))))

我需要创建一个附加最后两个流的函数,这样如果我运行

(stream-head (append-stream stream-of-even-natural-numbers stream-of-odd-natural-numbers) 4)

I get the output (0 2 1 3)

问题是,流是无限的,我不知道如何创建一个知道何时停止从第一个流获取输入然后继续从最后一个流获取输入的函数。

之前我做了两个列表的合并,看起来像这样;

>  (define (merge-streams s1 s2)  (cons (car s1)  (delay (merge-streams
> s2 (force!(cdr s1))))))

(stream-head (merge-stream stream-of-even-natural-numbers stream-of-odd-natural-numbers) 10)
= (0 1 2 3 4 5 6 7 8 9)

在这里我可以延迟,并交替从每个列表中选择哪个元素。

如何制定一个智能程序来附加列表?

【问题讨论】:

  • 附注:stream-head 有一个错误 - 它强制流中的元素过多,这可能会导致不必要的错误。 n==1不用强行拖尾,取car就行了,已经存在了。
  • 您的(0 2 1 3) 示例不足以消除合并与附加的歧义,以收集您的含义。您是否打算让(head (append ...) 6) 返回(0 2 4 1 3 5)(head (append ...) 8) 返回(0 2 4 6 1 3 5 7)?如果是这样,那似乎是不可能的。

标签: scheme


【解决方案1】:
(define (append-streams s1 s2)
  (cond
    [(empty-stream? s1) s2] 
    [(empty-stream? s2) s1]
    [else 
     (cons (stream-car s1) 
           (delay (append-streams (stream-cdr s1) s2)))]))

【讨论】:

  • 除了问题中没有显示empty-stream? 定义。
  • 明确说明流的表示方式也很好。在问题中使用了 thunk,但在上一个流问题中使用了 delay
  • 从发布的内容看来,这些流只能是无限的……也许发布不完整……
  • 如果是这样,我们可以写(define (append-streams s1 s2) s1)。但我认为你是对的,可能会遗漏一些东西。
  • 没错!事实上,我现在正在输入那个答案! :) 不知道我是否会发布它...
【解决方案2】:

根据您的显示,流只能是无限的。添加两个无限流很简单:

(define append-infinite-streams
  (lambda (s1 s2)
    s1))

如果你想要一个适应性强的附加,根据通过stream-head 调用它的方式来报告不同的东西,那么这组函数以及它们如何定义流的概念是不可能的。

即使您设法通过其他方案实现这一目标,这也是不明智的。流的较短前缀不应该始终是同一流的较长前缀的一部分吗?但你似乎想要

(define s3 (stream-append s1 s2))

(stream-head s3 6) 
=> (0 2 4 1 3 5) 

(stream-head s3 8) 
=> (0 2 4 6 1 3 5 7)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    相关资源
    最近更新 更多