SICP ex 2-16 2-21 Sequences

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值