
Scheme
文章平均质量分 61
keyboardOTA
喜欢技术挑战
展开
-
SICP 习题 (2.31)解题总结 : 通用的Square-Tree
SICP 习题 2.31 秉承该书一直以来的抽象作风,要求读者对习题2.30的结果进行抽象,使square-tree这种形式的过程更加通用。习题2.30中的square-tree只能对树状列表求平方,不能执行其他操作,但是我们可以发现其实使用map遍历树状列表的操作是通用的,只要我们将square换成其他过程就可以执行其他操作了。而Lisp里强大的将过程当做数据的功能可以帮助我们把square换原创 2016-07-16 21:50:34 · 1756 阅读 · 0 评论 -
SICP 习题 (2.20)解题总结: 不确定数量参数
SICP 习题 2.20 引入了一种新的函数调用方式,就是带 . 符号的不确定参数调用方式。题中也讲到了, Scheme支持这种调用方式,如果我们把方法定义成下面这个样子(define (my-method first-p . others-p) ;…..)我们就可以在调用方法my-method时传入大于2的任何数量的参数,比如:(my-method 1 2 3 4 5 6)这时my-原创 2015-01-08 23:30:42 · 2215 阅读 · 0 评论 -
SICP 习题 (2.21)解题总结: map的使用
SICP 习题 2.21 开始引入了map,准确来讲,是这道题目前的文章内容开始引入了map。为了完成本习题,甚至说为了完成本文以后的阅读,请读者一定要理解清楚map的概念,正如书中所说,“map是一种很重要的结构,不仅因为它代表了一种公共模式,而且因为它建立起了一种处理表的高层抽象”。虽然说得非常高大上,但是map的概念理解起来并不困难,最基本的理解就是给你一组东西,你对这组东西执行map操作的原创 2015-01-10 20:44:01 · 2299 阅读 · 0 评论 -
SICP 习题 (2.22)解题总结: 迭代过程中的列表处理
SICP 习题 2.22是习题2.21的后续题目,题目中讲到叫Louis Reasoner的人想重写suqare-list过程,希望使用迭代计算过程,而不是递归计算过程,有关迭代计算过程和递归计算过程,如果你没什么印象了,请翻回习题1.9 的解题总结看看。那个叫Louis Reasoner的人写的迭代版的suqre-list是这样的:(define (square-list-revert item原创 2015-01-12 00:07:50 · 3033 阅读 · 0 评论 -
SICP 习题 (2.19) 解题总结:重写零钱兑换程序
SICP 习题2.19 要求我们重新设计1.2.2节的零钱兑换程序,要求我们可以轻易改变程序里用的兑换币种。我们先看看1.2.2节的零钱兑换程序,代码是这样的:(define (RMB-Change amount) (format #t "Changing ~S~%" amount) (cond ((= amount 0) 0) ((< amount 0) 0) (else (RMB-原创 2015-01-07 00:14:14 · 2881 阅读 · 0 评论 -
SICP 习题 (2.14)解题总结:区间误差导致的问题
SICP 习题 2.14 的题目要求并没有完全体现在题干中,这道题是和书中前面的内容相关的。书中讲到,Alyssa做完了我们以前讨论的区间计算模块并发布出去了,然而,一段时间以后她接受到了来自一个叫做Lem的工程师的抱怨,这个叫做Lem的人应该是搞电路的,他用Alyssa的程序去计算两个电阻的并联电阻值,里面就使用了Alyssa设计的区间来表示一个电阻的电阻值。按照物理上的定律,并联电阻的公式是(原创 2014-12-16 16:33:43 · 11637 阅读 · 0 评论 -
SICP 习题 (2.11)解题总结:区间乘法的优化
SICP 习题 2.11又出现Ben这个人了,如以前说到的,只要是Ben说的一般都是对的。来看看Ben说什么,他说:“通过监测区间的端点,有可能将mul-interval分解为9中情况,每种情况中所需要的乘法都不超过两次”。所以这个叫Ben的人建议Allysa重写mul-interval过程。到底是啥意思呢,我们先来看看以前的mul-interval过程:(define (mul-interval原创 2014-10-29 00:31:35 · 56341 阅读 · 1 评论 -
SICP 习题 (2.13)解题总结:区间计算误差
SICP 习题 2.13 又像是一道数学证明题,和编程关系不大,不过这不能阻挡我们去完成它。题目要求我们证明,当误差百分比很小的时候,可以使用一个简单的公式,根据被乘区间的误差去计算乘积的误差。同时,为了简化问题,题目允许我们只计算所有数为正的情况,因为涉及到负数时,乘积的正负变化比较多样,不容易统一处理。我看到题目后最直接的反应不是去证明它,而是通过程序去找到这个简单的公式,典型的程序员心理。要原创 2014-11-23 15:39:42 · 33773 阅读 · 1 评论 -
SICP 习题 (2.5) 解题总结:复合数据的指数表示
SICP 习题 2.5 有点像是道数学题,首先要求我们证明可以将a和b的序对表示为2^a * 3^b,然后通过非负整数和算术运算表示序对。最后要求我们实现对应的cons, car 和cdr过程。这道题的根本就是复合数据的构成方式和解析方式。其实,对于所有复合数据来讲,我们都在处理同样一件事情,就是如何把复合数据的组成部分构建在一起,同时可以通过特定的方法将它们拆解出来。就好像我们要存放乒乓球和网球原创 2014-09-28 00:40:25 · 4743 阅读 · 0 评论 -
SICP 习题 (2.1) 解题总结:用复合数据表示有理数
SICP 习题 2.1 要求我们做一个可以正确处理正数和负数的make-rat过程,用于生成一个有理数。条件是分母必须是正数。完成这道题本身比较简单,就是简单修改一下书中的make-rat过程就可以了。书中原本的make-rat过程如下:(define (make-rat n d) (cons n d))可以发现,原来的make-rat就是简单地将n和d组成一个序对,然后返回这个序对,并没有对原创 2014-09-22 00:16:40 · 4796 阅读 · 0 评论 -
SICP 习题 (2.6) 解题总结:丘奇计数
SICP 习题 2.6 讲的是丘奇计数,是习题2.4 和 2.5的延续。 这里大师们想提醒我们思考的是“数”到底是什么,在计算机系统里可以如何实现“数”,准备好开始脑洞大开吧:题目先讲到下面的定义,首先是0的定义:(define zero (lambda (f) (lambda (x) x)))然后是操作+ 1的定义:(define (add-1 n) (lambda (f) (lambda原创 2014-09-29 00:33:09 · 6016 阅读 · 1 评论 -
SICP 习题 (2.4) 解题总结:序对的过程性表示
SICP 习题 2.4 是一道很有意思的题目,它在一定程度上会改变你对数据结构的认识。按题目的说法,这里讲到的是“序对的过程性表示”。序对大家应该熟悉了,前面几道题都和序对有关系,那序对的“过程性表示”是什么意思呢?简单一点说就是用一种过程(或者说函数啦)来实现序对。在此之前,对于很多程序员来讲,数据是数据,过程是过程,两者是单独存在的,过程一般是用来访问数据的。像这里讲到的使用一个过程来实现数据原创 2014-09-26 00:59:36 · 4043 阅读 · 0 评论 -
SICP 习题 (2.3) 解题总结:用复合数据表示矩形
SICP 习题 2.3 要求我们实现一种平面矩形的表示,定义获取数据的相关选择函数。然后定义几个过程来计算矩形的周长和面积。接着题目还要求我们实现矩形的另一种表示方式,要求这个新的矩形表示方式同样适用于以上定义的周长和面积计算过程。有关这道题我们可以通过由上而下的方式进行实现,实现过程也不算复杂,原因是这道题涉及到的数学概念还是比较简单,就是矩形的面积和周长,差不多是我们小学的知识吧。不过题目后面原创 2014-09-24 00:16:46 · 3970 阅读 · 0 评论 -
SICP 习题 (2.2) 解题总结:用复合数据表示点和线段
SICP 习题 2.2要求我们使用这一节的数据抽象方法定义几何里“点”的概念,还要定义“线段”的概念,最后还要求我们定义midpoint-segment过程,这个过程根据参数中的线段进行计算,返回该线段的中点。题目还给出了一个print-point过程,用于输出一个点,代码如下:(define (print-piont p) (newline) (display "(") (displ原创 2014-09-23 00:10:16 · 4023 阅读 · 0 评论 -
SICP 习题 (2.15)解题总结:区间误差的深入思考
SICP 习题 2.15 是接着 题目 2.14 的, 题目 2.14中提到了Alyssa设计的区间计算模块在并联电阻计算时会出现问题,这个问题是Lem发现的。接着,一个叫Eva的人也发现了这个问题,同时她还有更深入的思考。Eva觉得,如果一个公式可以写成一种形式,其中具有非准确性的变量不重复出现,那么Alyssa的系统产生的区间的限界会更紧一些。因此,她觉得在计算并联电阻时,公式“1/(1/R1原创 2014-12-23 22:23:36 · 2452 阅读 · 0 评论 -
SICP 习题 (2.16)解题总结:避免误差的区间计算系统
SICP 习题 2.16 问我们能不能设计一个没有问题的区间计算系统,可以避免习题2.14中的问题。题目还吓我们说这可能很难。这一下就把我吓住了,你不是说很难吗,那就很难吧,我不会。呵呵原创 2014-12-24 22:05:54 · 2820 阅读 · 2 评论 -
SICP 习题 (1.8) 解题总结:牛顿法求立方根
SICP 习题1.8需要我们做的是按照牛顿法求平方根的方法做一个求立方根的过程。 所以说书中讲牛顿法求平方根的内容还是要好好理解,不然后面这几道题做起来就比较困难。 反过来,如果理解了牛顿法求平方根的方法,做出一个求立方根的过程就很容易了。当然,我们需要一个改进猜测的方法,就是improve那部分,如果要我自己想出来这个改进方法我觉得是有挑战性的,还好书中直接写出来了,就是:((x / (y *原创 2013-09-02 00:12:31 · 3045 阅读 · 0 评论 -
SICP 习题 (2.24)解题总结:列表的结构
SICP 习题 2.24 是列表的巩固题,让我们更清晰的理解列表。题目要求我们求如下表达式的值:(list 1 (list 2 (list 3 4)))因为我是一个程序员,这种事我不会自己求值的,我会让计算机完成。。。。在Scheme环境里运行以上表达式得到的结果是:(1 (2 (3 4)))这个结果并不意外,相对有经验的程序员大概可以才出来。题目后来还要求画一个盒子指针结构将以上数据解释成一棵树原创 2015-01-19 00:19:00 · 2667 阅读 · 0 评论 -
SICP 习题 (2.25)解题总结:列表的操作
SICP 习题 2.25 简单到不用解释题目要求我们使用car和cdr操作获得以下列表中的7:'(1 3 (5 7) 9)'((7))'(1 (2 (3 (4 (5 (6 7))))))各位同学搞清楚car和cdr就可以简单完成了,代码如下:(define (start-test-2-25) (display (car (cdr (car (cdr (cdr '(1 3 (5 7) 9))原创 2015-03-02 23:27:51 · 1947 阅读 · 0 评论 -
SICP 习题 (2.26)解题总结:列表操作符append cons list
SICP 习题 2.26 也是不需要太多解释的题目, 题目的主要目的是让读者理解append cons list三个操作的差别。直接运行下面代码中的start-test-2-26过程就可以了,需要留意一下的是append 过程, cons过程和list过程的使用。最好翻一下mit-schme的参考手册,对了,一直没有提mit-scheme的手册,建议大家去下载一份备用,需要的时候查一查链接如下:原创 2015-03-02 23:29:01 · 2652 阅读 · 4 评论 -
SICP 习题 (2.27)解题总结:树状列表的遍历
SICP 习题 2.27 又开始有些难度了,题目要求我们实现reverse的升级版deep-reverse,就是不仅要将一个列表的元素顺序倒过来,还要将列表中所有子列表的元素也倒过来。想清楚思路以后也不算太难,其实就是在对所有元素进行倒转的过程中加多一个判断,如果正在处理的元素是一个列表,则对该列表递归调用deep-reverse过程,如果正在处理的元素是一个简单的元素则直接返回该元素。我的代码如原创 2015-09-27 14:29:33 · 1988 阅读 · 1 评论 -
SICP 习题 (2.28)解题总结:树状列表的遍历
SICP 习题 2.28 的本质其实是树的遍历题目要求我们实现一个叫fringe的过程,fringe的英文意思是边缘,花边的意思,题目的意思其实就是要我们遍历一棵树,然后以列表的形式返回这棵树的所有叶子。该过程的实现和上面的deep-reverse差不多,都是遍历元素,如果元素是一个列表则递归调用fringe进入,如果元素是一个简单元素则直接组合起来。代码如下:(define (fringe i原创 2015-09-27 14:30:34 · 2148 阅读 · 1 评论 -
SICP 习题 (2.29) 解题总结:二叉活动体
SICP 习题 2.29题目很长,实现起来有点繁琐,不过题目不难,花点时间还是容易完成的。题目引入了一个概念叫二叉活动体,这种东西有一个左分支,有一个右分支,每个分支包括一个长度和一个悬挂物,悬挂物可以是一个数,也可以是另一个二叉活动体。题中给出了二叉活动体的实现代码:(define (make-mobile left right) (list left right))也给出了分支的实现代码原创 2015-09-27 14:31:36 · 2265 阅读 · 1 评论 -
SICP 习题 (2.30)解题总结 : Square-Tree
SICP 习题 2.30 要求我们完成一个叫square-tree的过程,其作用和之前的square过程差不多,square过程是针对简单列表的,将列表中的所有元素求平方,然后返回新的平方数列表。不过square不能对嵌套列表进行处理,如果列表中还包含列表的话会报错。题目要求我们实现一个square-tree的过程,当输入的列表包含另一个列表时可以对嵌套的列表进行处理,生成所有列表元素的平方数。这原创 2015-09-27 14:32:05 · 2318 阅读 · 1 评论 -
SICP 习题 (1.11) 解题总结:加强版斐波那契数
SICP 习题 1.11相对简单一点,主要是里面没有太多数学问题,数学还是有一点,让这些数学天才们不使用数学样例它们可能宁愿不写书了。题目要求我们定义一个过程实现函数f,f的规则是:如果n如果n>=3那么f(n)= f(n-1) + 2f (n-2) + 3f(n-3)要求用递归实现一遍,然后用迭代实现一遍这个题目差不多是书中1.2.2节提到的“斐波那契数”的翻版,就是斐波那契数是前两个数相加,而原创 2013-09-12 00:10:10 · 4660 阅读 · 0 评论 -
SICP 习题 (1.7) 解题总结:改进版的牛顿法求平方根
SICP 习题 1.7 是对正文1.1.7节中的牛顿法求平方根的改进,改进部分是good-enough?过程。 原来的good-enough?是判断x和guess平方的差值是否小于0.001,这个过程在一般情况下没什么问题,但是,当需要求平方根的目标本身比较小时就会出现问题。 比如我们求(sqrt-iter 1.0 0.00000016),我们口算都知道结果是0.0004,但是(sqrt-iter原创 2013-08-26 23:37:39 · 3698 阅读 · 3 评论 -
SICP 习题 (2.17)解题总结:列表的遍历
SICP 习题 2.17 要求我们定义出过程last-pair,它返回只包含给定表里之后一个元素的表。比如 (last-pair (list 23 72 149 34))的结果应该是(34)当你开始做这道题的时候你应该已经看完书中有关list操作的内容了,你应该明白car和cdr分别是什么意思,也应该知道如何通过递归调用遍历一个list。有了以上基础的话完成习题2.17就是小菜一碟啦,基本思路就是原创 2014-12-25 00:12:01 · 2443 阅读 · 0 评论 -
SICP 习题 (2.18) 解题总结:反转列表
SICP 习题 2.18 要求我们定义一个过程名叫reverse,可以将一个list反转过来。比如 (reverse (list 1 4 9 16 25)) 的结果是:(25 16 9 4 1)这道题和之前的2.17有相似之处,都是对list进行遍历,然后做相应处理。不过2.17比较简单,遍历到最后面返回最后的元素就好了,2.18复杂一点,需要在遍历之后将list元素反向组装起来。我们可以按以前的原创 2014-12-25 00:13:10 · 3379 阅读 · 1 评论 -
SICP 习题 (1.46)解题总结:第一章的收官题
SICP 习题 1.46 要求我们写一个过程iterative-improve,它以两个过程为参数,其中一个参数用来检测猜测是否足够好,另一个参数用来改进猜测。过程iterative-improve应该返回另一个过程,所返回的过程接收一个参数作为初始猜测,然后不断改进猜测直到结果足够好。题目还要求我们使用iterative-improve重写1.1.7的sqrt过程和1.3.3节的fixed-po原创 2014-09-20 22:41:37 · 4283 阅读 · 1 评论 -
SICP 习题 (1.10)解题总结:阿克曼函数
SICP 习题 1.10 讲的是一个叫“Akermann函数”的东西,去百度查可以查到对应的中文翻译,叫“阿克曼函数”。就像前面的解题总结中提到的,我是一个数学恐惧者,看着稍微复杂一点的什么函数我就怕。所以这道题放了很久都没去动它,不过有担心跳过这道题对后面的学习不利,所以最终还是鼓足勇气尝试做这个题目。做完了我才发现,其实这道题真的可以跳过,做不做这道题似乎对后面的学习没什么影响。所以,如果你也原创 2013-09-09 22:55:22 · 4081 阅读 · 2 评论 -
SICP 习题(1.5)解题总结:应用序和正则序
习题1.5 主要讲的是函数参数的求值方式,包括应用序和正则序。解题前如果发现自己对应用序和正则序还不是太清楚,就需要重新看看1.1.5节“过程应用的代换模型”,对应用序和正则序有了较清楚的了解后解习题1.5就比较简单了。先看看题目,原创 2013-08-09 00:45:19 · 5724 阅读 · 2 评论 -
SICP 习题 (1.9) 解题总结:迭代计算过程和递归计算过程
SICP 习题 1.9 开始针对“迭代计算过程”和“递归计算过程”,有关迭代计算过程和递归计算过程的内容在书中的1.2.1节有详细讨论,要完成习题1.9,必须完全吃透1.2.1节的内容,不然的话,即使从网上找来答案看也不能理解其中的真谛。 书中1.2.1节是通过阶乘作为样例来讲解的,可能是因为作者们都是一些天才,所以他们都很喜欢使用数学样例,作为凡人的我们要理解他们在讲什么就需要先理解数学,真的是原创 2013-09-04 23:39:28 · 2839 阅读 · 3 评论 -
SICP 习题 (2.23)解题总结:for-each的实现
SICP 习题 2.23 要求我们实现一个for-each过程。for-each过程和map过程其实很像,只不过for-each过程不返回值,如果返回一个值的话也是不包含意义的值。map比较像一个加工厂,进去一堆东西,加工一下,出来另一堆东西。for-each更像一个蒸汽机,进去一堆煤,燃烧一下,产生能量干点活,不出来东西,真的一定要说有东西出来也是煤渣,大家不在乎的东西。所以for-each更关原创 2015-01-16 00:31:35 · 2464 阅读 · 0 评论 -
SICP 习题 (1.6) 解题总结:对if语句的特殊处理
SICP 习题 1.6 还是讲的正则序和应用序,问题是从if过程的讨论开始的,习题说到名叫Alyssa P. Hacker的人觉的不需要为if提供一种特殊形式,可以直接用常规过程调用cond来实现。 我第一次看到这道题的时候的反映是,if有特殊形式吗?没觉的if有什么特殊呀。有这样的反应是因为没有认真思考习题1.5。 我们上次看习题1.5的时候就看到习题有一个假设,就是不管是正则序还是应用序,都假原创 2013-08-14 06:58:01 · 5995 阅读 · 17 评论 -
SICP 习题 (2.10)解题总结: 区间除法中除于零的问题
SICP 习题 2.10 要求我们处理区间除法运算中除于零的问题。题中讲到一个专业程序员Ben Bitdiddle看了Alyssa的工作后提出了除于零的问题,大家留意一下这个叫Ben的人,后面会不断出现这个人,只要是这个人提到的事情一般是对的,他的角色定位是个计算机牛人。对于区间运算的除于零的问题,处理起来也比较简单,只需要判断除数是不是为零,除数为零就报错。对于一个区间来讲,所谓为零就是这个区间原创 2014-10-11 00:17:50 · 48096 阅读 · 0 评论 -
SICP 习题 (2.9)解题总结:区间的宽度和区间加减乘除的关系
SICP 习题 2.9 像是一个数学题,要我们证明区间的和与差的宽度是被加和被减的区间的宽度的函数,而对于乘法和除法来说不成立。书中所谓宽度就是区间起点和终点差的一半,以我看来更像是区间宽度的一半,不管怎么样,差不多是一个意思。如果你把区间看成是一个线段的话,所谓宽度应该就是起点和终点的差,如果一定要把宽度的一半记作是宽度也无所谓的。证明区间的和的宽度是被加区间的宽度的函数这一点是比较容易证明的,原创 2014-10-10 00:24:02 · 29471 阅读 · 0 评论 -
SICP 习题 (1.23) 解题总结
SICP 习题 1.23要求改进smallest-deivisor过程,因为samllest-devisor过程从2开始一直检测所有小于“根号n”的数,查找最小的因数。其实在检测了2以后就可以不再检测4,6,8,10等偶数,直接检查3,5,7,9等数就好了。 这题比较简单,就是定义一个过程,不断生成下一个奇数就好了,过程如下:(define (next-candidate n) (if (=原创 2014-02-11 23:36:15 · 2382 阅读 · 0 评论 -
SICP 习题 (1.26) 解题总结
SCIP 习题1.26是对expmod过程的讨论。 我不知道这道题对你来说是否简单,我个人是觉得比较简单。 题目说的是一个叫Louis Reasoner的人将expmod 过程实现成下面这个样子:(define (expmod base exp m) (cond (( = exp 0) 1) ((even? exp) (remainder (* (expmod base (/ exp原创 2014-02-26 00:27:16 · 3100 阅读 · 0 评论 -
SICP 习题 (1.24) 解题总结
SICP 习题 1.24 要求使用费马检测检测素数,可以说我的噩梦是从这道题开始的,从这道题开始的好几个星期内完全处于怀疑自己智商的状态中,因为我发现我要面对的不是会不会解题这个问题,而是我能不能理解题目的问题。 后来的努力证明,普通人也是可以理解复杂的数学问题的,所以各位可以继续努力!! 说到费马检测,首先是要去看看最朴素的素数检测方法,就是使用我们之前的smallest-divisor找最小因原创 2014-02-13 23:53:35 · 2713 阅读 · 0 评论 -
SICP 习题 (1.25) 解题总结
SICP 习题 1.25 就是我上面说过的伤自尊的题了。 习题1.25说到有个叫Allyssa P. Hacker的人说expmod过程完全没有必要搞那么麻烦,直接使用前面的fast-expt过程和remainder过程就好了,她(叫Alyssa的应该是女的吧)觉得可以这样定义expmod:(define (expmod base exp m) (remainder (fast-expt bas原创 2014-02-15 23:20:08 · 3559 阅读 · 0 评论