Scheme 为什么这个代码工作正常?
我认为下面的代码不能正确地删除前导零和尾随零,但它确实可以:Scheme 为什么这个代码工作正常?,scheme,racket,Scheme,Racket,我认为下面的代码不能正确地删除前导零和尾随零,但它确实可以: (define f (λ (l) (let loop () ; 1 (code line no.) (when (= 0 (first l)) ; 2 (set! l (rest l)) ; 3 (loop))
(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行),最后它将在第7行再次反转(第三次)
由于列表被反转了3次,所以输出应该是一个反转的列表(不带零),但是,输出中显示的是非反转列表。解释中的缺陷在哪里?您必须记住,当循环返回时,程序将在第4行之后继续执行。循环的每次调用都会发生这种情况。因此,如果有n个前导零和m个尾随零,
反向
将被称为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)
因此,我的直觉是正确的,这个代码不是完全正确的。你发布的代码不是你链接到的代码。这一个结合了变异和递归,这是一个令人不快的组合。你链接的那个完全是功能性的。我在发现链接有缺陷后更改了链接中的代码。我已经从我的问题中删除了链接。谢谢你指出这个疏忽。