方案车和cdr递归

时间:2013-10-06 16:46:40

标签: recursion scheme cons cdr

有人可以向我解释递归在以下函数中是如何工作的吗?具体来说,我感兴趣的是当函数达到其基本情况时会发生什么。另外,为什么在这段代码中使用了一个名为let? (我对名字让我不熟悉)

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
   (cons '() '())
   (let ((unzipped (unzip (cdr list-of-pairs))))
         (cons (cons (car (car list-of-pairs)) (car unzipped))
               (cons (cdr (car list-of-pairs)) (cdr unzipped))))))

1 个答案:

答案 0 :(得分:1)

所显示的程序没有任何特殊之处,您只需迭代此表单的列表:

'((1 . 2) (3 . 4) (5 . 6))

唯一的"奇怪的"部分是输出正在构建两个列表而不是通常的单个列表。如您所知,当我们将单个列表构建为输出时,基本情况如下:

(if (null? lst) '() ...)

但是在这里,鉴于我们同时建立了两个列表,基本情况如下:

(if (null? lst) (cons '() '()) ...)

问题中的代码没有使用named let,它只是一个普通的花园种类let,没有什么特别之处。它很有用,因为我们只想调用递归一次,因为我们需要从递归调用中获取两个值。

如果我们不介意效率低下,可以在不使用let的情况下编写过程,代价是在每一步调用递归两次:

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
      (cons '() '())
      (cons (cons (car (car list-of-pairs))
                  (car (unzip (cdr list-of-pairs))))
            (cons (cdr (car list-of-pairs))
                  (cdr (unzip (cdr list-of-pairs)))))))

当然,使用let的优点是它避免了双递归调用。