我有一个尾递归函数,它将一个向量转换为一个列表。我个别理解每一行,但有几个问题:
首先,在代码中代码cons ((vector-ref v i) r) (- i 1)
是什么意思? (标记为" Q1"。)我知道它需要向量i
的{{1}}'并将其与v
连接,但为什么必须是i-1
?为何不与i-1
合作?例如如果向量v长度为5,则元素5与数字4连接。我知道它正在制作向量列表,但为什么要使用i+1
(减少)?任何人都可以给我一个解释吗?
i-1
答案 0 :(得分:1)
明智地使用print语句来理解递归函数的工作原理非常有用。我添加了
(print r)
正下方
(lambda (vec r i)
我跑了命令:
(vector->list:rec (vector 1 4 6 8 9 10))
这是输出:
(10) (9 10) (8 9 10) (6 8 9 10) (4 6 8 9 10) (1 4 6 8 9 10) => (1 4 6 8 9 10)
第一次调用helper
时,使用列表调用它,该列表的唯一项是向量的最后一项:
(cons (vector-ref v (- (vector-length v) 1)) '())
使用
可以简化 (list (vector-ref v (- (vector-length v) 1)))
回答Q1
该行
(helper vec (cons (vector-ref v i) r) (- i 1)) ;; Q1
将(向量,cons
es)向量的i
元素预先添加到包含向量的i+1
及以上项的列表中。
在我运行的示例中,当i
为3
时,r
为(9 10)
。
如果我理解正确的话,这与你认为这句话所做的相反。
此函数从i
的最高有效值递归,并在每次递归调用中递减。这就是(- i 1)
作为上述helper
调用的最后一个参数的内容。
回答“另外,检查总长度在哪里?”
该行
(if (> (vector-length v) 0) ;; line 9
检查输入的总长度是否大于0.只有这样才会遇到调用helper
的麻烦。否则,它只返回一个空列表。
希望这有点道理。
答案 1 :(得分:0)
每次调用i
减少的原因是i
用于确定我们何时到达向量的末尾。我们的想法是,当我们最初调用helper
函数时,我们将i
设置为向量的长度(减去2),然后在每次递归调用中将i
减少1,直到它变得小于0,此时我们知道我们已经完成了整个向量。
我认为,导致您混淆的问题在于您正在正确解析cons
来电 - 计算括号表明该来电真的是(cons (vector-ref v i) r)
- (- i 1)
是只是helper
的第三个参数。
最后,在第9行检查向量的长度大于0的想法是,如果向量的长度为0,我们只想返回一个空列表'()
;如果我们没有进行此检查,那么如果我们输入空向量,那么对(vector-ref v (- (vector-length v) 1))
的调用将变为(vector-ref v -1)
,这显然会失败。我不确定“总长度检查”是什么意思,但(vector-length v)
确实返回v
的整个长度。