(计划)没有利弊的递归?

时间:2013-04-10 20:57:26

标签: vector scheme

此程序应根据给定的程序替换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为什么会出现。有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

请注意,consnull?与此答案无关,此处我们不处理列表。此外,您正在修改作为参数接收的一个向量,这不是最好的想法,但暂时忽略该事实。像往常一样,我会给你解决方案的一般结构,所以你可以弄清楚细节:

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