【发布时间】:2021-05-26 00:14:44
【问题描述】:
我正在通过一个练习来获取方案中嵌套列表的“叶子”(来自 SICP)。这是练习输入输出:
(define x (list (lis 1 2) (list 3 4)))
(fringe x)
; (1 2 3 4)
(fringe (list x x))
; (1 2 3 4 1 2 3 4)
现在,我为此想出了两个答案:一个是递归的,一个是迭代的。下面是我的两个实现:
(define (fr lst)
(cond ((null? lst) '())
((not (pair? (car lst))) (cons (car lst) (fr (cdr lst))))
(else (append (fr (car lst)) (fr (cdr lst))))))
(define (add-element-to-list lst elem)
(if (null? lst)
(list elem)
(cons (car lst) (add-element-to-list (cdr lst) elem))))
(define (fringe lst)
(define L '())
(define (iter lst)
(if (not (pair? (car lst)))
(set! L (add-element-to-list L (car lst))) ; update the list if it's a leaf
(iter (car lst))) ; otherwise recurse
(if (not (null? (cdr lst))) (iter (cdr lst))) ; and if we have a cdr, recurse on that
L
)
(iter lst)
)
(fringe x)
(fr x)
(fr (list x x))
(fringe (list x x))
; (1 2 3 4)
; (1 2 3 4)
; (1 2 3 4 1 2 3 4)
; (1 2 3 4 1 2 3 4)
; OK
对我来说,问题是,这个练习花了我很长时间才弄明白,一路上头疼不已(我写这篇文章时仍然很难“明白”)。以下是我努力解决的一些问题,看看是否有任何关于如何在方案中处理这些问题的建议:
- 我最初认为有两种情况。正常/标量情况和嵌套情况。然而,好像真的有三个!有普通的情况,嵌套的情况,然后是空的情况——内部列表也有空的情况!是否有一个很好的一般模式或什么来解释空情况?这是经常出现的事情吗?
- 在迭代的情况下,为什么我必须在最后返回
L?为什么(iter lst)不直接返回它(即,如果我删除了iter函数底部的standalone-L)。 - 最后,是否有一种“更简洁”的方式来实现迭代案例?看来我的代码太多了,可能还有待改进。
【问题讨论】:
-
不要使用
set!。 SICP 尚未引入它是有充分理由的。