请帮助我做一个关于该计划的简单练习。
写入函数,返回每个级别的原子数 名单。例如:
(a(b(c(d e(f)k 1 5)e))) - > ((11)(2 1)(3 2)(4 5)(5 1))
我的解决方案:
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
(define (count L)
(cond ((null? L) 0)
((pair? (car L))
(count (cdr L)))
(else
(+ 1 (count (cdr L))))))
(define (fun L level)
(cons
(list level (count L))
(ololo L level)))
(define (ololo L level)
(if (null? L)
'()
(if (atom? (car L))
(ololo (cdr L) level)
(fun (car L) (+ level 1)))))
(fun '(a (b (c (d e (f) k 1 5) e))) 1)
它工作正常,但没有正确回答此列表:
(a (b (c (d e (f) (k) 1 5) e)))
是:
((1 1) (2 1) (3 2) (4 4) (5 1))
但我们假设'f'和'k'在一个级别上,答案必须是:
((1 1) (2 1) (3 2) (4 4) (5 2))
我应该如何编辑代码才能使其正常工作?
UPD(29.10.12): 我的最终解决方案:
(define A '(a (b (c (d e (f) k 1 5) e))))
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
(define (unite L res)
(if (null? L) (reverse res)
(unite (cdr L) (cons (car L) res))))
(define (count-atoms L answ)
(cond ((null? L) answ)
((pair? (car L))
(count-atoms (cdr L) answ))
(else
(count-atoms (cdr L) (+ answ 1)))))
(define (del-atoms L answ)
(cond ((null? L) answ)
((list? (car L))
(begin
(del-atoms (cdr L) (unite (car L) answ))))
(else
(del-atoms (cdr L) answ))))
(define (count L)
(define (countme L level answ)
(if (null? L) (reverse answ)
(countme (del-atoms L '()) (+ level 1) (cons (cons level (cons (count-atoms L 0) '())) answ))))
(countme L 1 '()))
(count A)
你能说些什么呢?
答案 0 :(得分:2)
如果你这样做,你知道你得到了什么吗?
(fun '(a (b (c (d e (f) k 1 5) e)) (a (b (c)))) 1)
你明白了:
((1 1) (2 1) (3 2) (4 5) (5 1))
我在右侧添加的整个额外嵌套结构已被忽略。这就是为什么......
你的函数的每次递归都会做两件事:
一旦找到嵌套对,就会调用它。等等
当有趣从第一个嵌套对返回时, oLoLo 会发生什么?为什么,它回来了!它确实不继续沿着列表寻找另一个。
您的功能永远不会找到任何级别的第一个列表。如果确实如此,你会做什么从第一个列表到第二个列表添加计数?您需要仔细考虑如何通过包含多个嵌套列表和的列表完全重复,以了解如何在每个级别保留信息。这样做的方法不止一种,但你还没有找到任何一种方法。
答案 1 :(得分:0)
请注意,根据您的实现,此处使用的库可能需要以其他方式导入。找到必须导入的方式以及要使用的函数的确切名称可能非常困难。有些人会将其改为filter
和reduce-left
。 require-extension
可能是也可能不是Guile特有的,我真的不知道。
(require-extension (srfi 1))
(define (count-atoms source-list)
(define (%atom? x) (not (or (pair? x) (null? x))))
(define (%count-atoms source-list level)
(if (not (null? source-list))
(cons (list level (count %atom? source-list))
(%count-atoms (reduce append '()
(filter-map
(lambda (x) (if (%atom? x) '() x))
source-list)) (1+ level))) '()))
(%count-atoms source-list 1))
当然,正如我之前提到的,最好用哈希表来做这件事。使用列表执行此操作可能会产生一些教学效果。但是我非常强烈地反对教学效果,这些教学效果会让你写出糟糕的代码。