我认为以下代码无法正确删除前导零和尾随零,但确实如此:
(define f
(λ (l)
(let loop () ; 1 (code line no.)
(when (= 0 (first l)) ; 2
(set! l (rest l)) ; 3
(loop)) ; 4
(set! l (reverse l) ) ; 5
(when (= 0 (first l)) (loop))) ; 6
(reverse l))) ; 7
(f '(0 0 2 5 0 6 8 9 0 0 0))
输出:
'(2 5 0 6 8 9)
我认为在删除前导零之后,列表将在第5行中反转;然后从第6行开始,它将递归到第1行并删除尾随的零(现在在反向列表中领先)。然后这个列表将再次反转(第5次第5次),最后它将在第7行再次反转(第三次)。
由于列表反转3次,因此应该输出反转列表(不带零),但是输出中会显示非反转列表。解释中的缺陷在哪里?
答案 0 :(得分:2)
你必须记住,当循环返回时,程序继续在第4行之后执行。这发生在循环的每次调用中。因此,如果有n个前导零和m个尾随零,则reverse
将被称为n + 1 + m + 1 + 1 = n + m + 3
(最后1
在程序结束时反向),在示例情况下为8。
但是,你是正确的,因为该程序不能正常运行
(f '(0 0 2 5 0 6 8 9 0 0))
将输出
'(9 8 6 0 5 2)