【问题标题】:Recursive function in SchemeScheme中的递归函数
【发布时间】:2014-11-16 00:21:46
【问题描述】:

我需要创建一个递归函数,它接受一个对象和一个向量,并返回一个包含在我的对象参数之前的所有对象的列表。

我是这样使用迭代的:

(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 语句方面使用我之前使用的相同逻辑,但我不确定现在如何使用更新的向量调用相同的函数。任何帮助都会很棒。

【问题讨论】:

    标签: recursion scheme racket


    【解决方案1】:

    您正处于从迭代实现转向递归实现的有趣位置;通常人们会朝另一个方向走。幸运的是,从 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 正如我在开头提到的那样,这是一个相当有趣的案例,因为编写递归版本通常更容易,然后(在 Common Lisp 中,不一定有尾调用消除)使用 do 编写一个版本。我认为,朝另一个方向发展的情况不太常见。
    猜你喜欢
    • 1970-01-01
    • 2013-10-05
    • 2013-01-06
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    相关资源
    最近更新 更多