你好,我是Scheme的新手。
我在网上阅读教程,我想知道如何在Scheme中计算嵌套列表中原子的出现次数。我发现了一些提到bagify和flatten的教程;我试图将它们混合在一起,但我得到了一个错误。会出什么问题呢?
代码如下:
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
(define (flatten mylist)
(cond ((null? mylist) '())
((list? (car mylist)) (append (flatten (car mylist)) (flatten (cdr mylist))))
(else (cons (car mylist) (flatten (cdr mylist))) (bagify(mylist)))))发布于 2011-09-04 05:47:20
我认为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.
cdr.
car上的自然递归用二元运算符开始,该二元运算符与null?案例的左侧有意义,例如,+/0,*/1,cons/<car>D30null?>,<代码>D31/D32,https://stackoverflow.com/questions/7295584
复制相似问题