Lisp 每个级别上的原子数,方案
请帮我做一个关于这个计划的简单练习 Write函数,该函数返回 列表例如: (a(b(c(def)k15)e))–>((11)(21)(32)(45)(51)) 我的解决方案:Lisp 每个级别上的原子数,方案,lisp,scheme,Lisp,Scheme,请帮我做一个关于这个计划的简单练习 Write函数,该函数返回 列表例如: (a(b(c(def)k15)e))–>((11)(21)(32)(45)(51)) 我的解决方案: (define (atom? x) (and (not (pair? x)) (not (null? x)))) (define (count L) (cond ((null? L) 0) ((pair? (car L)) (count (cdr L))) (el
(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)))
是:
但我们假设‘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)
对此,你能说些什么?你知道如果你运行它会得到什么吗
(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))
我在右侧添加的整个额外嵌套结构已被忽略。这就是为什么
函数的每次递归都会做两件事:
您的函数在任何级别都不会找到超过第一个列表的内容。如果是这样的话,你会怎么做呢?把第一个列表中该级别的计数添加到第二个列表中?您需要仔细考虑如何在包含多个嵌套列表的列表中完全重复出现,以及如何在每个级别保留信息。有多种方法可以实现此目的,但您尚未了解其中任何一种。请注意,根据您的实现,此处使用的库可能需要以其他方式导入。可能很难找到导入它的方式以及要使用的函数的确切名称。有些人会将其作为
过滤器
和左减
<代码>需要扩展可能是也可能不是特定于欺诈,我真的不知道
(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))
当然,正如我前面提到的,最好使用哈希表。使用列表可能会产生一些教育效果。但我强烈反对说教式的效果,这种效果会让你编写出本质上糟糕的代码。我不知道如何在scheme中使用哈希表。此时此刻;)关于您的设计,还有一些其他方面:将初始级别指定给顶级函数是笨拙的,并且会导致错误;这是一个应该隐藏的内部实现细节(除非您真的想让用户选择从0或1开始)。创建一个函数(比如levelcount),只需将列表作为参数,声明其中的所有帮助函数,并让它将1(或0)传递给fun的初始调用这不是Guile特定的,但Guile和Gauche是我所知道的唯一支持它的开箱即用的实现。谢谢!很好的例子,我会试着理解并自己做:)谢谢,我已经意识到我的错误了。现在我需要考虑一下。我只是一个新手方案程序员。这是我学习函数式编程的第一步。再次感谢。对于新手来说,这是一个相对复杂的问题。你能回顾一下我的新解决方案吗?请:-)
(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))