(define (my-reverse ls)
(define (my-reverse-2 ls acc)
(if (null? ls)
acc
(my-reverse-2 (cdr ls) (cons (car ls) acc))))
(my-reverse-2 ls '()))
这使用累加器变量来反转列表,从传入列表中取出第一个元素并将其放在累加器的前面。它隐藏了累加器获取函数,只公开了获取列表的函数,因此调用者不必传入空列表。这就是为什么我有 my-reverse-2。
(my-reverse-2 '(a (b c d) e) '()); will call
(my-reverse-2 '((b c d) e) '(a)); which will call
(my-reverse-2 '(e) '((b c d) a)); which will call
(my-reverse-2 '() '(e (b c d) a)); which will return
'(e (b c d) a)
因为最后一个函数调用my-reverse-2
是一个电话my-reverse-2
,并且返回值直接传递(第一次调用的返回值is第二次调用的返回值,依此类推)my-reverse-2
is 尾部优化,这意味着它不会耗尽堆栈上的空间。因此,只要您愿意,可以安全地使用列表来调用它。
如果您希望它应用于嵌套列表,请使用如下内容:
(define (deep-reverse ls)
(define (deep-reverse-2 ls acc)
(if (null? ls)
acc
(if (list? (car ls))
(deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc))
(deep-reverse-2 (cdr ls) (cons (car ls) acc)))))
(deep-reverse-2 ls '()))
在将元素添加到列表之前,它会检查该元素是否是列表,如果是,则首先将其反转。
由于它调用自身来反转内部列表,因此它可以处理任意嵌套。
(deep-reverse '(a (b c d) e))
-> '(e (d c b) a)
尽管存在嵌套列表,但它是按字母顺序逆序排列的。
其评估如下:
(deep-reverse-2 '(a (b c d) e) '()); Which calls
(deep-reverse-2 '((b c d) e) '(a))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d) '(b)) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(d) '(c b)) '(a)))
(deep-reverse-2 '(e) (cons '(d c b) '(a)))
(deep-reverse-2 '(e) '((d c b) a))
(deep-reverse-2 '() '(e (d c b) a))
'(e (d c b) a)