这周我有新的作业要做,我应该写一个函数partSums
,它可以添加原始流中的元素来构建新的流,比如:
(element0,element0+element1,element0+element1+element2...)
并且该结果应当在开始时具有CCD_ 2。
在这个例子中,我假设我们有一个名为integers
的函数来生成一个像Haskell [1..]
中那样的流,所以在上面使用partSums
应该是这样的:
(partSums integers)
> '(1, 3, 6, 10, 15...)
在我的理解中,它是这样的:
1 2 3 4 5 6 7 8..
1 2 3 4 5 6 7..
1 2 3 4 5 6..
1 2 3 4 5..
1 2 3 4..
1 2 .
+ .
1 3 6 10 15 21 .....
添加我已经完成的2个流:
(define (add-streams s1 s2)
(cond ((empty-stream? s1) s2)
((empty-stream? s2) s1)
(else (cons-stream
(+ (head s1)(head s2))
(add-streams (tail s1) (tail s2))))))
我还有函数head
、tail
、cons-stream
,它们是流的car
、cdr
、cons
。
有人能帮我完成这个partSums
吗?
提前感谢
bearzk
HtDP机器人说:
- 你能为这个功能写一份目的声明和合同吗?它消耗什么,生产什么
- 你能把你的例子翻译成测试用例吗?写一个表达式,以及它应该产生的值。使用"相等?"进行比较
您的方法似乎是创建一组偏移的流并将它们相加。如果你知道你想取多少个元素,这是可以想象的,但如果元素的数量是不确定的,你当然不能创建无限数量的这些流!
另一种方法是维护在每个点添加的流的列表,称之为current-streams
,从(list integers)
开始。然后在每一步(cons integers current-streams)
,用(apply + (map head current-streams))
获得下一个部分和,并用current-streams
变为(map tail current-streams)
递归。通过这种方式,您只在真正需要的时候添加系列,而不是试图在前面创建无限数量的流。但这是一种资源密集型方法,因为需要跟踪的流的数量会不断增长。
如果您能将固定数量的流(最好是两个,使用您编写的函数!)相加以获得您想要的输出,那就太好了。请注意,在输出的每一步中,前一步都已经为您计算了所需的大部分部分和。。。如果你能找到一些使用流的方法来利用它。试着在你已经定义的0
0序列的帮助下,写下partSums
序列的连续元素之间的递归关系,看看这是否会让你找到一种可能不同的流式方法。。。
(define (partial-sums s)
(let loop ((current 0) (s s))
(if (empty-stream? s) '()
(let ((v (+ current (head s))))
(cons-stream v (loop v (tail s)))))))
这个
(partial-sums '(1 2 3 4 5 6 7 8 9))
打印
(1 3 6 10 15 21 28 36 45)
定义之后
(define empty-stream? null?)
(define tail cdr)
(define head car)
(define cons-stream cons)