说我有名单'(1 2 3(4 5 6)7 8 9)。它应该使用下面的代码返回(9 8 7(6 5 4)3 2 1)。我试图理解这个迭代过程是如何工作的。显示如何逐步完成这将非常有帮助。
我最困惑的部分是此时深度反向被调用两次 (附加 (深度反转(cdr lst)) (list(deep-reverse(car lst))))))
我不知道接下来会发生什么。
(define (deep-reverse lst)
(cond ((null? lst) '() )
((pair? (car lst))
(append
(deep-reverse (cdr lst))
(list (deep-reverse (car lst)))))
(else
(append
(deep-reverse (cdr lst))
(list (car lst))))))
答案 0 :(得分:3)
好吧,我刚刚回答了类似here的内容,但我并没有真正详细介绍深度逆转。
在将列表附加到列表末尾之前,它会反转每个恰好是列表的项目。想象一下如果它没有在列表的汽车上调用深度反转会发生什么:(reverse '(a (b c d) e)
是
(list
'e
'(b c d)
'a
)
使用深度反转时,它看起来像
(list
'e
(deep-reverse '(b c d))
'a
)
哪个是
(list
'e
'(d c b)
'a
)
这是深度反转的另一个版本,如果更清楚,则以不同的方式编写。
(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)); If adding a list, reverse it first
(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)); which is the same as
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a))); it calls deep-reverse on the list '(b c d) before consing it on.
(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)
答案 1 :(得分:0)
很简单,你不知道头是整数还是列表,所以你也必须在它上面应用deep-reverse
,然后将它附加到当前列表的反向尾部。
所以:
((1 2) 3 4)
必须成为
(4 3 (2 1))
注意我们如何扭转头部和尾部。