简体   繁体   English

Scheme中的递归函数

[英]Recursive function in Scheme

I need to make a recursive function that takes an object and a vector and returns a list of all the objects that preceded my object parameter. 我需要创建一个递归函数,该函数需要一个对象和一个向量,并返回在我的对象参数之前的所有对象的列表。

I did it using iteration like this: 我使用这样的迭代来做到这一点:

(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))
)

but I'm having a lot of trouble trying to figure out how to do the same thing using recursion. 但是尝试弄清楚如何使用递归进行相同的操作时遇到了很多麻烦。 I'm confused how I can keep incrementing through the vector as I recursively call. 我很困惑如何在递归调用时如何不断增加向量。 So far, all I have is this: 到目前为止,我所拥有的只是:

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

I figured I would use the same logic I used before in terms of the if statement, but I'm not sure how to now call the same function with the updated vector. 我以为我会使用与if语句相同的逻辑,但是我不确定现在如何使用更新的向量调用相同的函数。 Any help would be great. 任何帮助都会很棒。

You're in the interesting position of moving from an iterative implementation to a recursive one; 您处于从迭代实现过渡到递归实现的有趣位置。 usually people go in the other direction. 通常人们朝另一个方向走。 Fortunately, moving from a do -loop to recursion is pretty easy. 幸运的是,从do循环到递归非常简单。 In general, a do loop can be rewritten as follows: 通常,可以将do循环重写如下:

(do ((i i-init i-step)
     (j j-init j-step)
     ...)
    (test result)
  body)

becomes

(define f (i j ...)
  (cond
    (test result)
    (else body (f i-step j-step ...))))

(f i-init j-init ...)

That translation is usually written using a named let, though: 不过,该翻译通常使用命名的let编写:

(let f ((i i-init)
        (j j-init)
        ...)
  (cond
    (test result)
    (else body (f i-step j-step ...))))

So (and I haven't tested the code) your original function 所以(我还没有测试代码)您的原始功能

(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))
)

would turn into 会变成

(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))))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM