您需要了解什么是列表,并且要非常熟悉它才能成为一个好的 lisper。该列表(1 2 3)
只是对的视觉糖,(1 . (2 . (3 . ())))
可以用(cons 1 (cons 2 (cons 3 '())))
该结构(((((5) . 4) . 3) . 2) . 1)
不是一个列表,除了(5)
它是(5 . ())
. 它可以用(cons (cons (cons (cons (cons 5 '()) 4) 3) 2) 1)
当您列出清单时,您需要从头到尾列出。当你遍历一个列表时,你会从头到尾遍历它。要在处理时以与您的参数相同的顺序获取列表,您需要使用递归,以便您当前的步骤等到尾部的处理完成,直到最终结果是锥体在一起,或者您使用累加器来处理列表完成后反转和反转结果。
似乎您正在尝试反转列表,然后只是在迭代列表时累积列表:
(define (reverse lst)
(define (reverse-aux lst acc)
(if (null? lst)
acc
(reverse-aux (cdr lst) (cons (car lst) acc))))
(reverse-aux lst '()))
如您所见,我定义了一个辅助函数来获取第三个参数,然后使用它。大多数计划者更愿意在一个操作中同时使用一个命名的let
(define (reverse lst)
(let reverse-aux ((lst lst) (acc '()))
(if (null? lst)
acc
(reverse-aux (cdr lst) (cons (car lst) acc)))))
这些是完全相同的。通常在进行迭代时,许多人使用名称loop
代替,reverse-aux
但它可以是任何名称,我选择保留第一个示例中的名称。
没有捷径可走。你需要能够看((a b) c (d))
和思考(( a . (b ())) . (c . ((d . ()) . ())
,所以你需要做很多练习。
对于在进行 SICP 时使用 DrRacket 中的什么语言,请查看我之前的回答。