Scheme中的递归函数

时间:2014-11-16 00:21:47

标签: 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 vec)) list))
)

但是我在尝试弄清楚如何使用递归做同样的事情时遇到了很多麻烦。当我递归调用时,我很困惑如何继续通过向量递增。到目前为止,我只有这个:

(define (precedes2 obj vec)
  (define list '())
  (if (eqv? obj (vector-ref vec i))
      (cons(vector-ref vec(- i 1)) list)
      list)))

我认为我会使用与之前使用的if语句相同的逻辑,但我不确定现在如何使用更新的向量调用相同的函数。任何帮助都会很棒。

1 个答案:

答案 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))))))