SICP 第一章的练习
没想到家里网欠费了,家人没回来,只能看书度日了….
于是乎翻了图书馆借来快一个月的SICP,开看…
(该记录,包含书中的大部分练习,以及一些书中内容的感受,做了85%~90%的代码题)
还有scheme的正则序、应用序求值,还有if、cond、define这些特殊形式等等知识。
代码慢慢整理,先贴上加上一些自己的理解,代码的顺序和练习的都差不多,所以有点懒得求标题号了(懒
(看了大概4天了,当然实际的时间并没那么多,刚好算是看完第一章,第一章大多都是数值计算,练习做完的感觉,从开始对递归与迭代的陌生,在高级语言如C++或者脚本python中有for while 之类的循环来写迭代,而在scheme(lisp的方言)上,都是以递归写,然后来写递归过程与迭代过程,感觉自己对递归的写法更加掌握以及理解,以及迭代的理解,在看的过程中,发现很多抽象思想很好,值得去学习,还算是复习到了一些数学知识以及了解一些数值计算方法,还有gcd的写法,以前傻不拉几的一步一步用循环迭代写,现在发现了短短几行的递归代码就能实现,也了解到了计算中数学的重要性)
#lang planet neil/sicp(define (inc x)(+ x 1))
(define (dec x)(- x 1))
(define (square x)(* x x))(define (max x y z)(define (max-iter x y)(if (< x y) y x))(if (= (max-iter x y) y) (max-iter y z) (max-iter x z))) (define (sqrt x)(define (sqrt-iter val rval)(define (b-enough val rval) //bad-way(< (abs (- (* val val) rval)) 0.0001))(define (g-enough val rval) //good-way 与bad的区别在于是用前后比例,避免了要求的数小于误差(< (/ (abs (- val (improve val rval))) (improve val rval)) 0.0001))(define (average x y)(/ (+ x y) 2))(define (improve x y)(average x (/ y x)))(if (g-enough val rval)val(sqrt-iter (improve val rval) rval)))(sqrt-iter 1.0 x))(define (cube x) //求立方根(define (cube-g-enough val rval)(< (/ (abs (- val (c-improve val rval))) (c-improve val rval)) 0.0001))(define (c-improve y x)(/ (+ (/ x (* y y)) (* 2 y)) 3))(define (cube-iter val rval)(if (cube-g-enough val rval)val(cube-iter (c-improve val rval) rval)))(cube-iter 1.0 x))(define (Jc x) //求阶乘(if (> x 0) (* x (Jc (- x 1))) 1))(define (dd-Jc x) //迭代的方式(define (iter result count n)(cond ((= count (inc n)) result)((= n 0) 1)(else (iter (* result count) (inc count) n))))(iter 1 1 x))//下面两个函数是一个关于,把1美元=100美分,划分为1、5、10、25、50的种类个数
//如果让我不看题解,我直接想到的方法就是用5重循环,求解解的个数。
//当然如果仔细分析,你就会发现这是一个动态规划的问题
//我们把钱类排序,步骤一:不用第一种面值进行计算的划分数目,用另外几种划分钱。
// 步骤二:使用第一种面值后,用剩下的钱用所有面值划分的数目。
//然后这两个步骤加起来的就是所有可分配的种数。
//因为步骤一,不使用第一种面值划分,步骤二使用了第一种面值来划分,则两者数目相加就是总数。
//然后有递推公式 f(money,kinds)=f(money,kinds-1)+f(money-moneyKinds[kinds],kinds) 成立.
//这就是数学的魅力么..我开始看也是不太理解,不过仔细想这合理。
(define (moneyKinds kinds) (cond ((= kinds 1) 1)((= kinds 2) 5)((= kinds 3) 10)((= kinds 4) 25)((= kinds 5) 50)))
(define (type-count money kinds)(define (f m n)(cond ((= m 0) 1)((or (< m 0) (= n 0)) 0)(else (+ (f m (- n 1)) (f (- m (moneyKinds n)) n)))))(f money kinds))//练习题 dg-递归 dd-迭代
(define (dg-f n)(cond ((< n 3) n)(else (+ (dg-f (dec n)) (* 2 (dg-f (dec (dec n)))) (* 3 (dg-f (dec (dec (dec n)))))))))(define (dd-f n)(define (iter x y z count n)(if (= count n) x(iter (+ x (* 2 y) (* 3 z)) x y (+ count 1) n)))(iter 2 1 0 2 n))//杨辉三角,二项式系数,即便你不会二项式通式,可以根据书上的三角形归纳
// f(m,n)=f(m-1)(n-1)+f(m)(n-1),n为三角形的序号,m为层数
(define (cc m n)(if (or (= m 0) (= m n) ) 1(+ (cc (dec m) (dec n)) (cc m (dec n)))))
//even偶数,remainder为计算余数
//本来想写一个求余数,但是没有取整的方法或者不知道,计算出来的要么是分数,要么是循环小数..
(define (is-even n)(= (remainder n 2) 0))// b^n=(b^(n/2))^2 (n偶数)
// b*b^(n-1) (奇数)
(define (fast-exp m n)(define (iter result m n)(cond ((= n 0) 1)((= n 1) (* m result))((is-even n) (iter result (* m m) (/ n 2)))(else (iter (* result m) m (dec n)))))(iter 1 m n))//bad 这是没看懂题意写的,而且计算的规模是-1的速度,很慢
//good 折半,因为乘法可以用加法表示,a x b = (a * 2) x (b/2) b偶数
// a x b = a x (b - 1) + a b奇数
(define (fast-mulit m n)(define (double x)(+ x x))(define (halve x)(/ x 2))(define (b-iter result a b) //bad(cond ((= b 0) 0)((= b 1) (+ a result))(else (b-iter (+ result a) a (- b 1)))))(define (g-iter result a b) //good (cond ((= b 0) 0)((= b 1) (+ a result))((is-even b) (b-iter result (double a) (halve b)))(else (g-iter (+ a result) a (- b 1)))))(g-iter 0 m n))// 根号n的检验素数
(define (prime n) (define (div a b)(= (remainder a b) 0))(define (find-div n cheak )(cond ((> (square cheak) n ) n)((div n cheak) cheak)(else (find-div n (+ cheak 2) ))))(define (smallest-div n)(find-div n 2)(= (smallest-div n) n)) //快速检测素数,以及费马检测,若 n 是素数,则有a<n,a^n mod n =a
//若n不是素数,有部分依旧满足以上,有部分不满足,通过多次检验,若不符合则不是素数。。
(define (expmod m n p)(cond ((= n 0) 1)((is-even n) (remainder (square (expmod m (/ n 2) p)) p))(else (remainder (* m (expmod m (- n 1) p)) p))))(define (fermat-test n)(define (try a)(= (expmod a n n) a))(try (+ (random (- n 1)) 1)))
//写这个想起了写timer..
(define (fermat-timer n times)(cond ((= times 0) true)((fermat-test n) (fermat-timer n (- times 1)))(else false)))
//(fermat-timer 5 10) test//上数值分析课的时候似乎碰见过,但是不认真听讲,用C/C++按公式打过一遍
//第一种m-的是我想不到怎么按书上例子,不使用sum编写的
//百度过别人的做法,似乎计算出错还是怎么
//辛普森解法结果为 0.25147191134420877,感觉100的步数,精确度比书上例子的差,不过1000步数的精度好用一些
(define (m-sympson f a b n)(define h (/ (- b a) n))(define (func k)(f (+ a (* k h))))(define (iter result k)(if (> k n) result(iter (+ result (func k)) (inc k))))(* (/ h 3) (iter 0 0)))
//练习1.30叫填空...我就把上面的补充进去了,使用了例子的sum,算是对上面的一种完善..?
(define (c-sympson f a b n)(define h (/ (- b a) n))(define (func k)(f (+ a (* k h))))(define (next x)(inc x))(define (sum term a next b)(define (iter result k)(if (> k n)result(iter (+ result (func k)) (next k))))(* (/ h 3) (iter 0 0)))(sum func 0 next n))//(c-sympson cube 0 1 100.0) test//看规律有,会发现奇数项,分子比分母小1,偶数项,分子比分母大1
//根据这个规律推出一个递推式 a>b 则下一项 a=a,b=a+1,否则a=b+1 b=b, a b初始值是2 3
//通过判断n奇偶,来使用a b判断第n项(define (pi-mulit n)(define (iter a b result)(cond ((and (is-even n) (= a (+ n 2))) (* result (/ a b)))((and (not (is-even n)) (= b (+ n 2))) (* result (/ a b)))((> a b) (iter a (inc a) (* result (/ a b))))(else (iter (inc b) b (* result (/ a b))))))(iter 2.0 3.0 1))//(pi-mulit 2000) test//递归方式重写上面
//重写的完成时候,对递归和迭代的理解相对之前明了许多(我感觉写的不太像递归过程..)
//对比两种方法:
//我们在迭代的时候,是使用初始值,根据规律,推到后面的每一项,且每计算完一项就保存从之前到现在的结果
//而递归,我们是从后面,也就是第n项,根据规律,往前推,不需要设置初始值,只需要保存当前项的结果
//递归展开后,就把之前的结果一层一层返回合并着算
//这两道解题并没有按照书上的要求写要给factorial来写(即写一个类似于书上sum的mulit)(define (dg-pi-mulit n)(define (iter n r)(cond ((= n 0) r)((is-even n) (* r (iter (dec n) (/ (+ n 2) (inc n)))))((not (is-even n)) (* r (iter (dec n) (/ (inc n) (+ n 2))))))) (iter n 1.0))//(dg-pi-mulit 100) test //关于上面中提出的sum和mulit,也就是[a,b]内求和与求积公式
//可以把他们写成下面两种形式
//term函数相当于把初始化a序号的数据格式,next就相当于是下一项
(define (plus-f term a next b)(if (> a b)0(+ (term a) (plus-f term (next a) next b))))
(define (mulit-f term a next b)(if (> a b)1(* (term a) (mulit-f term (next a) next b)))//理解上面着两个,你就可以按照下面这样写,我昨天没理解大意//上面两种就是递归求和,与求积的大概形式,我前面大多都是写迭代//所以前面写的都不是基于着两种写的//使用mulit-f :
(define (dg-mulit-pi n)(define (next x)(+ x 1))(define (iter n)(cond ((is-even n) (/ (+ n 2.0) (inc n)))((not (is-even n)) (/ (inc n) (+ n 2.0)))))(mulit-f iter 1 next n))//(dg-mulit-pi 100) test//因为plus-f与mulit-f代码相同的部分很多
//我们还可以进一步抽象化,让代码更简洁明了
//combiner可以看作逻辑符号、运算符之类,或者是两个参数的过程函数,value则是d对应combiner的一些数
(define (accumulate combiner value term a next b)(if (> a b)value(combiner (term a) (accumulate combiner value term (next a) next b))))
//测试accumulate,还是上面算pi/4的值功能
(define (test-accul n)(define (next x)(+ x 1))(define (iter n)(cond ((is-even n) (/ (+ n 2.0) (inc n)))((not (is-even n)) (/ (inc n) (+ n 2.0)))))(accumulate * 1 iter 1 next n))//添加过滤器版本的-accmulate
(define (filter-accul filter combiner value term a next b)(if (> a b)value(combiner (filter (term a)) (filter-accul filter combiner value term (next a) next b))))
//[a,b)中所有素数的求和
(define (ss-sum a b)(define (next x)(inc x))(define (filter x)(if (prime x) x 0))(define (iter x) x)(filter-accul filter + 0 iter a next b))
//gcd
(define (gcd n m)(if (= m 0)n(gcd m (remainder n m))))
//<n与n互素的正整数乘积
(define (mulit-hs n)(define (next x)(inc x))(define (filter x)(if (= (gcd x n) 1)x1))(define (iter x) x)(filter-accul filter * 1 iter 1 next n))//(mulit-hs 5) test(define (fixed-point f guess)(define (is-enough v1 v2)(< (/ (abs (- v1 v2)) v2) 0.0001))(define (iter guess)(let ((next (f guess)))(newline)(display next)(if (is-enough guess next)next(iter next))))(iter guess))(define (gold-line x)(+ 1 (/ 1 x)))
(define (test-sin x)(sin x))
(define (test-log x)(/ (+ x (/ (log 1000) (log x))) 2))
//无穷连式递归,写出函数,确定改变项,迭代或者递归次数
(define (cont-frac n d k)(define (iter r k)(let ((term (lambda (x) (/ n (+ d x)))))(if (= k 0)r(iter (term r) (dec k)))))(iter 2.0 k))(define (dd-cont-frac n d k)(define (iter c)(let ((term (lambda (x) (/ n (+ d x)))))(if (= c k)2.0(term (iter (inc c))))))(iter 1))//第一级状态
(define (cubic a b c)(lambda (x) (+ (* x (square x)) (* a (square x)) (* b x) c)))
(define (f-double f)(lambda (x) (f (f x))))(define (compose f g)(lambda (x) (f (g x))))(define (repeated f n)(define (iter n x)(if (= n 1)(f x)(f (iter (dec n) x))))(lambda (x) (iter n x)))(define (smooth f)(lambda (x) (/ (+ (f (- x 0.0001)) (f x) (f (+ x 0.0001))) 3)))//((repeated (smooth (lambda (x) (square x))) 5) 5) test
SICP 第一章的练习相关推荐
- sicp第一章部分习题解答
(begin(load "util.scm");ex 1.16 计算b的幂 (define (_expt product b n maxn)(if (= n maxn) produ ...
- 王道考研 计算机网络笔记 第一章:概述计算机网络体系结构
本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 后续章节将陆续更新- 目录 一.概念.功能.组成.分类 1. 计算机网络的概念 2. 计算机网络功能 3. 计算 ...
- 计算机组成原理-第一章
计算机组成原理第一章概述 一.计算机系统概述 1. 定义 2.分类 3.计算机系统的抽象层次 二.计算机系统的组成 1.计算机系统的硬件组成 1.1冯.诺依曼计算机(重点) 1.2现代计算机结构 1. ...
- 山西农业大学c语言答案,第一章C语言及程序设计概述-东北农业大学教务处.doc...
全国高等农林院校"十一五"规划教材 C语言程序设计 孙力 主编 中国农业出版社 内容简介 本书是全国高等农林院校"十一五"规划教材之一. 全书共11章,分别介绍 ...
- Python3-Cookbook总结 - 第一章:数据结构和算法
第一章:数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. ...
- 《零成本实现Web自动化测试--基于Selenium》第一章 自动化测试基础
第一篇 Selenium 和WebDriver工具篇 第一章 自动化测试基础 1.1 初识自动化测试 自动化测试有两种常见方式 1.1.1 代码驱动测试,又叫测试驱动开发(TDD) 1.1.2 ...
- 华南理工网络计算机基础知识,2019年华南理工大学网络教育计算机基础随堂练习第一章...
2019年华南理工大学网络教育计算机基础随堂练习第一章 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 11.90 积分 第一章 计算机基础知识·第 ...
- CCNA 第一章 网际互联
第一章 网际互联 路由器知识点: 1.默认时,路由器不转发任何广播包和组播包. 2.路由器使用逻辑地址,逻辑地址在网络层的包头中,用来决定将包转发到的下一跳路由器. 3.路由器可以使用管理员创建的访问 ...
- 2018-3-31(Nature-Inspired metaheuristic Algoritjms Second Edition第一章)笔记-优化,寻优,元启发式算法
第一章-----Introduction' 1.1 一些歌概念: x: design or decision variables 设计或决策变量 f(x) :Objective function ...
- Android项目驱动式开发教程 第2版,《Android项目驱动式开发教程》第一章开发入门.ppt...
<Android项目驱动式开发教程>第一章开发入门 1.4 项目框架分析 4 android:versionName="1.0" > 5 8 第9行代码andro ...
最新文章
- 《权力的游戏》最终季上线!谁是你最喜爱的演员?这里有一份Python教程 | 附源码...
- 理解什么是MyBatis?
- 数字货币支付能成为主流吗?
- ICLR 2020将采用远程会议,首次在非洲办会可能就这样泡汤了
- 图解 navicat for oracle 的使用
- 软件工程的瀑布, 大泥球, 教堂,集市,和银弹
- html保存助手,HTML助手与HTML助手内
- 命令行方法查看和设置环境变量
- How to connect iOS simulator to Chrome for debugging
- 10玩rust_C++工程师的Rust迁移之路(5)- 继承与组合 - 下
- 手动封装js的call和apply和bind和typeof和new方法
- 种草!这只鹅虽然没有什么用,但是好可爱呀!
- ConcurrentHashMap 源码
- Mybatis Plus 的BaseMapper 和 Model有什么用
- 配置ftp方式的yum源的各种排错
- UML类图各符号含义
- Virident:PCIe SSD更能发挥闪存的特长
- 编程老司机带你玩转 CompletableFuture 异步编程
- 高通设备进入高通9008模式
- 小程序列表页制作优惠券效果