我需要创建一个递归函数,它接受一个对象和一个向量,并返回一个在我的对象参数之前的所有对象的列表。
我使用迭代这样做:
(define (precedes obj vec)
(do ((i 1 (+ i 1))
(list '() (if (eqv? obj (vector-ref vec i))
(cons(vector-ref vec (- i 1)) list)
list)))
((= i (vector-length vec)) list))
)
但是我在尝试弄清楚如何使用递归做同样的事情时遇到了很多麻烦。当我递归调用时,我很困惑如何继续通过向量递增。到目前为止,我只有这个:
(define (precedes2 obj vec)
(define list '())
(if (eqv? obj (vector-ref vec i))
(cons(vector-ref vec(- i 1)) list)
list)))
我认为我会使用与之前使用的if语句相同的逻辑,但我不确定现在如何使用更新的向量调用相同的函数。任何帮助都会很棒。
答案 0 :(得分:2)
你处于从迭代实现转向递归实现的有趣位置;通常人们走向另一个方向。幸运的是,从执行 -loop转移到递归非常简单。通常,可以按如下方式重写 do 循环:
(do ((i i-init i-step)
(j j-init j-step)
...)
(test result)
body)
变为
(define f (i j ...)
(cond
(test result)
(else body (f i-step j-step ...))))
(f i-init j-init ...)
该翻译通常使用命名let来编写,但是:
(let f ((i i-init)
(j j-init)
...)
(cond
(test result)
(else body (f i-step j-step ...))))
所以(我还没有测试过代码)你原来的功能
(define (precedes obj vec)
(do ((i 1 (+ i 1))
(list '() (if (eqv? obj (vector-ref vec i))
(cons(vector-ref vec (- i 1)) list)
list)))
((= i (vector-length vec)) list))
)
会变成
(define (precedes obj vec)
(let loop ((i 1)
(list '()))
(cond
((= i (vector-length vec)) list)
(else (loop (+ i 1)
(if (eqv? obj (vector-ref vec i))
(cons (vector-ref vec (- i 1)) list)
list))))))