双倍计划
(define double
(lambda (x)
(cond ((null? x) (list))
((list? (car x)) (cons (double (car x)) (double (cdr x))))
(else (cons (* 2 (car x)) (double (cdr x)))))))
编辑 修正这一点。感谢Nathan Sanders指出我对嵌套列表的初步监督。
怎么样(double'(1(2 3)(4 5))) – 2010-02-25 17:37:33
这听起来像你想要的是在s表达式中找到每个整数,然后将其加倍,同时保持其余部分相同。
如果你不知道,s表达式只是可能会包含其它链表,它是有道理的来对付他们的水平。例如,这里有一个方法来打印上的S-表达的一个级别的所有值:
(define (print-level-one sexp)
(display (car sexp))
(print-level-one (cdr sexp)))
这将最终调用上的S-expression的每一个部分的car
显示。
你可以做类似的事情。您需要使用integer?
和pair?
这两个函数来检查是否有一个整数(应加倍)或另一个列表,它应该像*列表一样处理。
(注意:我是故意含糊其词,因为关于上述功课的评论如果你只是想要的答案,而不是帮助找出答案,这么说,我会改变这一点)
An Sexp of numbers is one of
-- Number
-- ListOfSexp
A ListOfSexp is one of
-- empty
-- (cons Sexp ListOfSexp)
所以,你需要一个函数来处理这两个数据定义。由于数据定义彼此交叉引用,所以这些功能也会执行相同的操作。每个单独的功能都非常简单。
(define (double E)
(cond ((null? E) '())
((list? (car E)) (cons (double (car E)) (double (cdr E))))
((number? E) (list E))
(else (cons (* 2 (car E)) (double (cdr E))))
))
(map (lambda (x) (* x 2)) '(1 2 3 4 5)) => '(2 4 6 8 10)
它有什么作用? (lambda (x) (* x 2))
需要一个数字并将其加倍,map
将该函数应用于列表的每个元素。
编辑:哦,但它不会进入树木。
我们要接受一个S-表达式作为输入,并且输出S-表达具有相同的结构,但是其中每个整数被加倍的过程;一般地,程序映射S-表达式:
(define (double x) (if (number? x) (* x 2) x))) (define (sexp-map op sexp) ...) (sexp-map double some-sexpression)
我们得到(SEXP)将是任一种原子,在这种情况下,结果是(OP SEXP),或S的一个列表中的S-表达-expressions。在这种情况下,我们可能会考虑将OP映射到SEXP上,但S表达式任意嵌套。我们实际上应该做的是映射一个过程,该过程将用OP转换较小S表达式中的每个元素。那么你会看看,这只是描述我们目前正在编写的过程的目标的另一种方式。所以我们可以将SEXP-MAP映射到SEXP。
好了,没有我们做不到的实际,因为SEXP-MAP需要用两个参数来调用,MAP只会给它一个。为了解决这个问题,我们使用一个参数的帮助程序F:
(define (sexp-map op sexp) (define (f x) (if (list? x) (map f x) (op x))) (f sexp))
F结束了所有的实际工作。SEXP-MAP被简化为一个更容易被程序员使用的外观。
这听起来很像作业,在这种情况下,你应该添加“家庭作业”标签。 – 2010-02-25 17:21:16
因为你所有的问题都是在过去的10天里,并且在你的作业中关于Scheme的'how-to',我会推荐Friedman和Felleison的The Little Schemer。在完成1或2章之后,像这样的问题将变得轻而易举(并且您不必为了答案而去SO)! 或者如何设计程序http://htdp.org/ 祝您的课程顺利! – 2010-02-25 17:59:31