SICP ex 2-16 2-21 Sequences

来源:互联网 发布:mac如何获取最高权限 编辑:程序博客网 时间:2024/04/28 15:04
ex2-16 2-17 2-18要求给出线性表的最后一个元素值,将线性表倒置,以及对每个元素进行平方操作
给出最后一个元素比较简单,我们直接利用递归检测直到下一个元素为空,我们给出本元素的值即可
将线性表倒置,由于之前我简单尝试了自己编写append函数,发现倒置挺麻烦的,所以思路很简单,直接利用迭代的方式就可以实现倒置
每个元素进行平方,类似于append要创建一个顺序的list ,我们运用递归方式先展开后合并,最后结果就是顺序的
以下为代码
(define (last x)(if (null? (cdr x)) (car x)(last (cdr x))))(define (reserve x)(let ((tmp (list)))(define (iter a tmp) (if (null? a) tmp(iter (cdr a) (cons (car a) tmp))))(iter x tmp)))(define (square-list x)(if (null? x) ()(cons (square (car x)) (square-list (cdr x)))))

接下来的问题是给出了一个存在bug的代码,问题是输出结果倒置,
有了上面的经验,我们很快就明白,它使用了迭代的方式
拿1 2 3 4来说,他先计算1的平方,然后(cons 1 nil)
然后再去计算2的平方(cons 4 (cons 1 nil))
这里看下结果为(4 1)显然是倒置的
而我们的递归方式的会由于无法求得值,所以先展开,到最后的时候最里面的括号开始求值,因此是顺序的
以下是bug代码
;;this code has a bug(define (square-list x)(define (iter list answer)(if (null? list)answer(iter(cdr list)(cons (square (car list)) answer))))(iter x ()))

之后,进行修改,将cons中answer与(square (car list))进行对调,显然,这种做法是错的
我们简单分析一下,在某次迭代中假设answer已经是一个非空列表,然后我们调用cons
我们直接看一下结果
为什么这答案长得这么丑呢,我们简单分析一下,由于我们是把answer作为pair的前项
我们默认的answer为nil,因此我们最终结果为(nil,1,4,9,16)而正确的结果应为(1,4,9,16,nil)
显然还是错了
至于正确的写法,请看前面2-19
ex2-20
本题要求运用high-order思想,抽象之前的square-list函数
比较简单,直接上代码
(define (mapcar f x)(if (null? x) ()(cons (f (car x)) (mapcar f (cdr x)))))


ex2-21
要求修改曾经的找零问题(第一篇博客 一下子写了这么多了)
使用list 来提高代码重复使用性
比较简单,直接给代码
(define (cc amount kinds-of-coins)(cond ((= amount 0) 1)((or (< amount 0) (no-more? kinds-of-coins)) 0)(else (+ (cc (- amount (first-denomination kinds-of-coins)) kinds-of-coins)  (cc amount (except-first-denomination kinds-of-coins))))))(define (no-more? kinds-of-coins)(null? kinds-of-coins))(define (except-first-denomination kinds-of-coins)(cdr kinds-of-coins))(define (first-denomination kinds-of-coins)(car kinds-of-coins))

0 0
原创粉丝点击