理解尾递归向量 [英] Understanding a tail-recursive vector

查看:38
本文介绍了理解尾递归向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个尾递归函数,可以将向量转换为列表.我单独理解每一行,但有几个问题:

I have a tail-recursive function which converts a vector into a list. I understand each line individually, but have a couple questions:

首先,在代码中cons ((vector-ref v i) r) (- i 1) 是什么意思?(标记为Q1".)我知道它需要向量 v 的第 i 个元素并将它与 i-1 连接起来,但是为什么必须是 i-1?为什么不使用 i+1?例如如果向量 v 长度总共为 5,则元素编号 5 与编号 4 连接.我知道它正在制作向量列表,但为什么要使用 i-1(减少)?谁能给我一个解释?

Firstly, in the code what does the code cons ((vector-ref v i) r) (- i 1) mean? (Marked "Q1".) I know that it takes the i'th element of vector v and concatenates it with i-1, but why have to be i-1? Why not work with i+1? e.g. if the vector v length is total 5, then element number 5 is concatenated with the number 4. I understand that it is making the vector list, but why work with i-1 (reducing)? Can anyone give me an explanation?

(define vector->list:rec
 (lambda (v)
   (letrec ((helper
          (lambda (vec r i)
            (if (< i 0) 
                r
                (helper vec (cons (vector-ref v i) r) (- i 1))  ;; Q1
                ))))
     (if (> (vector-length v) 0)  ;; line 9
      (helper v (cons (vector-ref v (- (vector-length v) 1)) '()) (- (vector-length v) 2))
      '()))))

推荐答案

i 每次调用减少的原因是 i 用于确定我们什么时候已经到达向量的末尾.这个想法是,当我们最初调用 helper 函数时,我们将 i 设置为向量的长度(减去 2),然后在每次递归调用中减少 i 乘以 1,直到它小于 0,此时我们知道我们已经遍历了整个向量.

The reason why i is decreasing with each call is that i is used to determine when we've reached the end of the vector. The idea is that when we call the helper function initially, we set i to be the length of the vector (minus 2), and then in each recursive call decrease i by 1 until it becomes less than 0, at which point we know that we've gone through the whole vector.

我相信,导致您困惑的问题是您对 cons 调用的解析不正确 - 计算括号向我们表明该调用确实是 (cons (vector-ref vi) r) - (- i 1) 只是 helper 的第三个参数.

The issue causing your confusion, I believe, is that you're parsing the cons call incorrectly- counting the parentheses shows us that the call is really (cons (vector-ref v i) r) - the (- i 1) is just the third argument to helper.

最后,在第 9 行检查向量长度大于 0 的想法是,如果向量的长度为 0,我们只想返回一个空列表 '();如果我们不做这个检查,那么对 (vector-ref v (- (vector-length v) 1)) 的调用将变成 (vector-ref v -1) 如果我们输入一个空向量,这显然会失败.我不确定您所说的总长度检查"是什么意思,但是 (vector-length v) 确实返回了 v 的整个长度.

Finally, the idea of checking in line 9 that the length of the vector is greater than 0 is that if the vector's length is 0, we just want to return an empty list '(); if we didn't do this check, then the call to (vector-ref v (- (vector-length v) 1)) would become (vector-ref v -1) if we input an empty vector, which would obviously fail. I'm not sure what you mean by "total length checking", but (vector-length v) does indeed return the entire length of v.

这篇关于理解尾递归向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆