此程序应根据给定的程序替换vec1中的值。因此,如果过程是+
,那么它将用每个元素的总和替换vec1中的每个值。例如:
~ (define v (vector 1 2 3 4 5 6))
~ (vector-join v + v)
~ v
#(2 4 6 8 10 12)
我知道递归存在问题,但我不知道如何修复它。我只学会了如何使用cons进行递归,我认为在这类问题中做的不正确。
到目前为止,这是我的代码:
(define v (vector 1 2 3 4 5 6))
(define (vector-join vec1 pre vec2)
(define (help v1 proc v2 i)
(if (null? v1) v1
(if (null? v2) v1
(if (>= i (vector-length v1)) v1
(cons (vector-set! v1 i (proc (vector-ref v1 i) (vector-ref v2 i)))
(help v1 proc v2 (add1 i)))))))
(help vec1 pre vec2 0))
当我输入时:
(vector-join v + v)
它返回:
(#<void> #<void> #<void> #<void> #<void> #<void> . #(2 4 6 8 10 12))
最后一部分是正确的答案,但我不知道#voids
为什么会出现。有什么帮助吗?
答案 0 :(得分:0)
请注意,cons
,null?
与此答案无关,此处我们不处理列表。此外,您正在修改作为参数接收的一个向量,这不是最好的想法,但暂时忽略该事实。像往常一样,我会给你解决方案的一般结构,所以你可以弄清楚细节:
(define (vector-join vec1 pre vec2)
(define (help v1 proc v2 i)
(cond (<???> v1) ; what's the exit condition?
(else
<???> ; set the current value at position `i`
<???>))) ; advance the recursion, no consing here!
(help vec1 pre vec2 0))
退出条件将是“当i
在向量之外时”,并且在正常情况下我们会在移动到更新之前更新向量中的当前位置(由i
表示)下一个位置。递归将推进索引;鉴于我们正在修改v1
,这就是我们将在程序结束时返回的内容。它按预期工作:
(define v (vector 1 2 3 4 5 6))
(vector-join v + v)
=> '#(2 4 6 8 10 12)
这个程序的编写方式让人想起一个命令式语言的解决方案。不寻常的部分(对于Scheme程序来说)就是这样一个事实:在第二个<???>
中你正在改变一个数据结构(在这种情况下是一个向量),但你只是为了效果< / em>,而不是值 - vector-set!
操作没有返回有用的值,这解释了问题代码中显示的所有#<void>
。