当前位置: 首页 > news >正文

SICP 习题(1.1,1.2,1.3,1.4)解题总结。

近来在重读SICP,以前读过一次,读了第一二章就没有坚持下去,时间一长就基本忘记了,脑海里什么都不剩,就隐约记得自己曾经读过一本很牛B的书。

这次读希望能够扎实一点,不管能读到哪里,希望可以理解一些东西,以后可以在日常工作中用到,所以开始一道一道地做题,强迫自己深入学习。

后来发现效果不错,于是产生了写解题总结的想法,可以和大家分享,同时加深自己的印象。因为是工作之余才有时间写总结,所以也不能确定更新时间,能写多少是多少吧。


前面几道题比较简答,所以就将1.1,1.2,1.3,1.4这四道题合在一起写了。


1.1的题目是写出一系列表达式的输出结果。

题中列出的表达式里主要是+,-,*,/四则运算,cond和if的使用,还有define的使用。具体表达式就不列出来了,解这道题建议分两步,第一步是拿纸笔做,目的是深入了解Scheme的基本语法,第二步是搭建mit-scheme环境逐步去验证自己第一步做的答案,目的是搭建mit-scheme环境,熟悉mit-scheme环境的使用。如果发现对不上的话就同时检查两边的结果,看是自己用纸笔算错了还是代码写错了,记住,不一定计算机算出来就是对的,我自己就有纸笔算对了,然后通过计算机运行时因为输入错误导致代码出错的。


1.2 是将一个表达式转换成前缀表达式。

这道题认真一点慢慢做的话没什么难度,属于RPG游戏里刚开始那种引导性的角色,按步就班一招一式下来就完成任务了。主要目的是熟悉前缀表达式。

同样,建议手算一遍,在mit-scheme环境里跑一遍,然后对对结果。


1.3 的原题是这样的:请定义一个过程,它以三个数为参数,返回其中较大的两个数的和。

我刚开始做这道题的时候,怀着对SICP的无比崇敬,总觉得会有一个特别聪明的方法,左思右想不敢开始写代码。

后来终于屈服于“自己不是天才”的想法,老老实实写了下面的代码:

(define (sum-larger-two x y z)
  (cond ((and (< x y) (< x z)) (+ y z))
	(else (cond ((< y z) (+ x z))
		    (else (+ x y))))))
简单测试通过,后来就去网上找答案,发现原来大家的解法都差不多,都是几个判断组合起来。有趣的是网上的答案五花八门,各种条件的组合都有,有兴趣的同学们可以去找找看。

回过头来看这道题的话,主要就是看你对cond或者是if的使用了,能够正确地写完cond或者是if的完整结构就能解这道题了。


1.4 的题目如下:

请仔细考察上面给出的允许运算符为复合表达式的组合式的求值模型,根据对这一模型的认识描述下面过程的行为:

(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))

题目本身有点绕,什么“允许运算符为复合表达式的组合式的求值模型”,看一轮下了不知道题目说的啥。其实就是说+ 和-这样的运算符可以当作返回值,返回以后就真的当运行符使用。

就像上面的代码,如果b>0就返回+,否则就返回-,同时,返回的+或者-就直接作为a和b的运算符,理解了这一点上面的代码就很清晰了。

做到这里已经感觉到SICP的强大气场了,大家手上用的编程语言没几个可以将运算符当返回值用的吧,而且返回后真的就当运算符用!

同样的,在Scheme里,或者说在Lisp里,运算符是可以当参数传到过程里的。

就这个后来还有人演绎成一个故事叫《四个程序员的一天》,引起无数程序员的惊叹,同时也引起无数程序员的不满。


如果你曾经为《四个程序员的一天》感叹过,那么,请注意,该故事中强大的Lisp程序员使用的那招不过是SICP中第一章起步的一个小练习而已。

就像是《大雨商家堡》中阎基打败大镖头马行空的那几招不过是《胡家刀法》中前面两页的入门招数而已。




相关文章:

  • linux终端开发环境的配置
  • ADO.NET理论+实践
  • Android实战技术:深入理解Android的RPC方式与AIDL
  • Linux调试器工作原理——基础篇
  • Linux调试器工作原理之二——实现断点
  • 学ACM有用吗?
  • Linux调试器工作原理之三——调试信息
  • hdu1501 Zipper
  • Android实战技术:理解Binder机制
  • SICP 习题(1.5)解题总结。
  • android开发图片分辨率
  • 用接口,多态,继承,类计算三角形和矩形的周长和面积
  • 通过应用实例讨论Java多态的实现
  • Win32_9SetWindowRgn函数的应用——绘制个性化形状的窗口
  • Android DEX安全攻防战
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 230. Kth Smallest Element in a BST
  • canvas绘制圆角头像
  • Docker容器管理
  • HTTP 简介
  • java8-模拟hadoop
  • Java超时控制的实现
  • PHP CLI应用的调试原理
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Redux 中间件分析
  • Vue.js 移动端适配之 vw 解决方案
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 微服务框架lagom
  • 为视图添加丝滑的水波纹
  • 用Visual Studio开发以太坊智能合约
  • 鱼骨图 - 如何绘制?
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • (10)ATF MMU转换表
  • (Java数据结构)ArrayList
  • (ZT)薛涌:谈贫说富
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (五)Python 垃圾回收机制
  • (一)RocketMQ初步认识
  • (正则)提取页面里的img标签
  • (转)为C# Windows服务添加安装程序
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net 简单实现MD5
  • .net 托管代码与非托管代码
  • .NET 中让 Task 支持带超时的异步等待
  • .NET/C# 使窗口永不获得焦点
  • .NET的微型Web框架 Nancy
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET学习教程二——.net基础定义+VS常用设置
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项