我觉得bagify
和flatten
对于这类问题熏鲱鱼。当然,你可以使用flatten
,然后计算结果拼合列表中的出现次数。但是,仅仅遍历嵌套列表会更加高效和直接。
为了简单起见,我们首先实现非嵌套情况下的函数。下面是计算的'?
出现一个版本,甚至更简单:
(define count-?s
(lambda (ls)
(cond
[(null? ls) 0]
[(eq? (car ls) '?) (add1 (count-?s (cdr ls)))]
[else (count-?s (cdr ls))])))
改变这种对嵌套列表只需要添加一个cond
线上工作。您发现的flatten
的实现包含一个提示:我们希望检查递归的每一步是否列表的car
本身是一个列表(但是,使用list?
比我们需要的功率更大;我们可以使用pair?
代替只要我们的输入总是一个适当的嵌套列表)。
一旦我们知道car
也是一个(可能嵌套的)列表,我们需要将它传递给一个知道如何处理列表的函数。幸运的是,我们正在定义一个!
(define count-?s*
(lambda (ls)
(cond
[(null? ls) 0]
[(pair? (car ls)) (+ (count-?s* (car ls)) (count-?s* (cdr ls)))]
[(eq? (car ls) '?) (add1 (count-?s* (cdr ls)))]
[else (count-?s* (cdr ls))])))
这就是它的全部。很少涉及到,不是吗?这么少,事实上,你可以只更换一对夫妇的表情和风能与做某事嵌套列表完全不同的功能:
(define remove-?s*
(lambda (ls)
(cond
[(null? ls) '()]
[(pair? (car ls)) (cons (remove-?s* (car ls)) (remove-?s* (cdr ls)))]
[(eq? (car ls) '?) (remove-?s* (cdr ls))]
[else (cons (car ls) (remove-?s* (cdr ls)))])))
求解嵌套列表的一个问题是很容易的,一旦你”已经解决了它的平面列表。
- 从平面列表解决方案开始。
- 检查
car
中的一对。
- 对
car
和cdr
都进行自然递归。
- 合并的答案与二元运算有意义与
null?
壳体的左侧,例如,+
/0
,*
/1
,cons
/'()
,and
/#t
,or
/#f
。
哇...非常感谢你... Scheme对我来说有点奇怪,但它很有趣。再次,非常感谢。 =) –