Recursion 格式中的递归函数
我需要做一个递归函数,它接受一个对象和一个向量,并返回一个在我的对象参数之前的所有对象的列表 我是这样使用迭代的:Recursion 格式中的递归函数,recursion,scheme,racket,Recursion,Scheme,Racket,我需要做一个递归函数,它接受一个对象和一个向量,并返回一个在我的对象参数之前的所有对象的列表 我是这样使用迭代的: (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 v
(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语句中使用的相同逻辑,但我不确定现在如何使用更新的向量调用相同的函数。任何帮助都会很好。您正处于从迭代实现转向递归实现的有趣位置;通常人们往另一个方向走。幸运的是,从do循环到递归非常容易。通常,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))))))
感谢您提供有关逻辑的详细信息。真的帮助我更好地理解这门语言。就像2周前刚开始用Scheme编码一样。@Ganda正如我在开始时提到的,这是一个相当有趣的案例,因为编写递归版本通常比较容易,然后(在公共Lisp中,不一定要消除尾部调用)使用do编写版本。我认为,朝另一个方向走不太常见。