有人可以向我解释递归在以下函数中的工作原理吗?具体来说,我对函数达到其基本情况时会发生什么感兴趣。另外,为什么在此代码中使用命名 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 . 2) (3 . 4) (5 . 6))
唯一"奇怪"的部分是输出是构建两个列表而不是通常的单个列表。如您所知,当我们构建单个列表作为输出时,基本情况如下:
(if (null? lst) '() ...)
但在这里,鉴于我们同时构建两个列表,基本情况如下所示:
(if (null? lst) (cons '() '()) ...)
题中的代码没有使用命名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
的好处是它避免了双重递归调用。