1

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

4

1 回答 1

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 程序)是这样一个事实,即在第二个中<???>你正在改变一个数据结构(在这种情况下是一个向量),但你这样做只是为了效果,而不是为了价值 -vector-set!操作不会'不返回有用的值,它解释#<void>了问题代码中显示的所有内容。

于 2013-04-10T21:14:38.603 回答