the little schemer 笔记(5)
第五章 “Oh My Gawd”:It's Full of Stars
(rember* a l)是什么,其中a是cup,l是((coffee) cup ((tea) cup) rember*发音为rember-star
((coffee ((tea) cup) (and (hick)) cup)
(rember* a l)是什么,其中a是suace,l是(((tomato sauce)) ((bean) sauce) (and ((flying)) sauce))
(((tomato)) ((bean)) (and ((flying))))
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainland License.
现在写出函数rember*,下面是框架
(define rember*
(lambda (a l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? x)
(and (not (pair? x))
(not (null? x))))
(define rember*
(lambda (a l)
(cond
((null? l) (quote ()))
((atom? (car l))
(cond
((eq? a (car l)) (rember* a (cdr l)))
(else (cons (car l) (rember* a (cdr l))))
(else (cons (rember* a (car l)) (rember* a (cdrl)))))))))
(lat? l)是什么值,其中l是(((tomato sauce)) ((bean) sauce) (and ((flying)) sauce))
#f
(car l)是atom吗
不是
(insertR* new old l)是什么值,其中new是roast, old是chuck,l是((how much (wood)) could ((a (wood) chuck)) (((chuck))) (if (a) ((wood chuck))) could chuck wood)
((how much (wood)) could ((a (wood) roast)) (((roast))) (if (a) ((wood roast))) could roast wood)
现在写出函数 insertR*,下面是框架
(define insertR*
(lambda (new old l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? x)
(and (not (pair? x))
(not (null? x))))
(define insertR*
(lambda (new old l)
(cond
((null? l) (quote()))
((atom? (car l)) (cond
((eq? old (car l)) (cons old (cons new (insertR* new old (cdr l)))))
(else (cons (car l) (insertR* new old (cdr l))))))
(else (cons (insertR* new old (car l)) (insertR* new old (cdr l)))))))
insertR*和 rember*有什么相似之处
当car是一个list时,他们都有car的递归。
所有的*-函数都有什么相似之处
都有三个分支查询,当car是一个list时,car和cdr一样也要递归。
为什么
因为所有的*-函数的list参数都是要么空要么里边有原子被cons到list中,要么有list被cons到list中。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
第一戒 (最终版)
递归时至少要有一个参数变化,并且向终止条件方向变化。变化的参数必须有终止测试条件:当递归原子,lat时使用(cdr lat)。当递归数n时使用(sub1 n)。当递归一个 S-expression的列表l,当(null? l)或者(atom? (car l))使用(car l)和(cdr l)。
递归时参数要向终止条件方向变化:当使用cdr时,用null?测试终止;当使用sub1时,用zero?测试终止。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(occursomething a l),其中a是 banana,l是((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy))
5
那么 occursomething 的好点的名字是什么
occur*
写一个函数occur*
(define insertR*
(lambda (a l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? a)
(and (not (null? a)) (not (pair? a))))
(define occur*
(lambda (a l)
(cond
((null? l) 0)
((atom? (car l))
(cond
((eq? a (car l)) (add1 (occur* a (cdr l))))
(else (occur* a (cdr l)))))
(else (+ (occur* a (car l)) (occur* a (cdr l)))))))
'((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy))
(occur* 'banana '((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy)))
DrRacket环境测试结果为
欢迎使用 DrRacket, 版本 5.1.3 [3m].
语言: 大; memory limit: 64 MB.
((banana)
(split ((((banana ice))) (cream (banana)) sherbet))
(banana)
(bread)
(banana brandy))
5
(subst* new old l), 其中new是orange,old是banana,l是((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy))
((orange) (split ((((orange ice))) (cream (orange)) sherbet)) (orange) (bread) (orange brandy))
写一个函数subst*
(define subst*
(lambda (new old l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? a)
(and (not (null? a)) (not (pair? a))))
(define subst*
(lambda (new old l)
(cond
((null? l) (quote ()))
((atom? (car l))
(cond
((eq? old (car l))
(cons new (subst* new old (cdr l))))
(else (cons (car l)
(subst* new old (cdr l))))))
(else (cons (subst* new old (car l))
(subst* new old (cdr l)))))))
'((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy))
(subst* 'orange 'banana '((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy)))
DrRacket环境测试结果为
欢迎使用 DrRacket, 版本 5.1.3 [3m].
语言: 大; memory limit: 64 MB.
((banana) (split ((((banana ice))) (cream (banana)) sherbet)) (banana) (bread) (banana brandy))
((orange) (split ((((orange ice))) (cream (orange)) sherbet)) (orange) (bread) (orange brandy))
(insertL* new old l)是什么,其中new是pecker,old是chuck,l是
((how much (wood)) could ((a (wood) chuck)) (((chuck))) (if (a) ((wood chuck))) could chuck wood)
写一个函数 insertL*
(define insertL*
(lambda (new old l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? a)
(and (not (null? a)) (not (pair? a))))
(define insertL*
(lambda (new old l)
(cond
((null? l) (quote ()))
((atom? (car l))
(cond
((eq? old (car l))
(cons new
(cons old
(insertL* new old (cdr l)))))
(else (cons (car l)
(insertL* new old (cdr l))))))
(else (cons (insertL* new old (car l))
(insertL* new old (cdr l)))))))
'((how much (wood)) could ((a (wood) chuck)) (((chuck))) (if (a) ((wood chuck))) could chuck wood)
(insertL* 'pecker 'chuck '((now much (wood)) could ((a (wood) chuck)) (((chuck))) (if (a) ((wood chuck))) could chuck wood))
DrRacket环境测试结果为
欢迎使用 DrRacket, 版本 5.1.3 [3m].
语言: 大; memory limit: 64 MB.
((how much (wood)) could ((a (wood) chuck)) (((chuck))) (if (a) ((wood chuck))) could chuck wood)
((now much (wood))
could
((a (wood) pecker chuck))
(((pecker chuck)))
(if (a) ((wood pecker chuck)))
could
pecker
chuck
wood)
(nember* a l),气质那个a是 chips,l是 ((potato) (chips (( with) fish) (chips)))
#t,因为原子chips在列表l中。
写出函数member*
(define member*
(lambda (a l)
(cond
(_____ _____)
(_____ _____)
(_____ _____))))
(define (atom? a)
(and (not (null? a)) (not (pair? a))))
(define member*
(lambda (a l)
(cond
((null? l) #f)
((atom? (car l))
(or (eq? a (car l))
(member* a (cdr l))))
(else (or (member* a (car l))
(member* a (cdr l)))))))
'((potatoes) (chips (( with) fish) (chips)))
(member* 'chips '((potato) (chips (( with) fish) (chips))))
DrRacket环境测试结果为
语言: 大; memory limit: 64 MB.
((potato) (chips ((with) fish) (chips)))
#t
(leftmost l)是什么,其中l是((potatoe) (chips ((with) fish) (chips)))
potato
(leftmost l)是什么,其中l是(((hot) (tuna (and))) cheese)
hot
(leftmost l)是什么,其中l是(((() four)) 17 (seventeen))
没有答案
(leftmost (quote()))是什么
没有答案
你能描述leftmost是什么
这是我们的描述
“函数leftmost查找S-expression表达式中非空list中的的最左边的一个原子。
leftmost是一个*-函数吗
它的参数为 S-expression构成的表达式,但是仅在car上递归。
leftmost需要所有的三种分支查询吗
不,仅需要两个。我们已经确认 leftmost的参数是非空表并且没有空表成员。
现在看看你能不能写出 leftmost函数
(define leftmost
(lambda (l)
(cond
(_____ _____)
(_____ _____))))
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define leftmost
(lambda (l)
(cond
((atom? (car l)) (car l))
(else (leftmost (cdr l))))))
还记得(or ...)是做什么的吗
(or ...) 一次查询一个直到出现真然后停下来,返回真。如果找不到真,那么(or ...)的值是假。
假设x是pizza,l是(mozzarella pizza),那么(and (atom? (car l)) (eq? (car l) x))的值是多少
#f
为什么是false假
因为(and ...)查询(atom? (car l)),是真,但是(eq? (car l) x)是假。于是为假。
假设x是pizza,l是((mozzarella) pizza)那么(and (atom? (car l)) (eq? (car l) x))的值是什么
为什么
因为(and ...)查询(atom? (car l)),但是(car l)不是一个atom。于是为#f
举个x和l的例子让(and (atom? (car l)) (eq? (car l) x))为真
下面是一个例子:x是pizza,l是(pizza (tastes good))
请用自己的话描述一下(and ...)的作用
下面是我们的描述
"(and ...)一次查询一个,直到出现否,然后返回假。如果总找不到假的表达式,(and ...)的值为真。
判断真假:(and ...)和(or ...)的有些参数没有查询
是的。(and ...)当找到#f时就停止了。(or ...)当找到t时就停止了。
注:(cond ...)也有不查询参数的时候。因为这个特性,(and ...) 和(or ...)也可以由(cond ...)定义:
(and alpha beta)=(cond (alpha beta) (else #f))
(or alpha beta)=(cond (alpha #t) else beta)
问当l是(strawberry ice cream),l2是(strawberry ice cream)问(eqlist? l1 l2)是什么
#t
问当l是(strawberry ice cream),l2是(strawberry cream ice)问(eqlist? l1 l2)是什么
#f
问当l1是(strawberry ice cream),l2是(strawberry cream ice)问(eqlist? l1 l2)是什么
#f
问当l1是(beef ((sausage)) (and (soda))),l2是(beef ((salami)) (and (soda)))是什么
#f,差一点就是#t真
问当l1是(beef ((sausage)) (and (soda))),l2是(beef ((sausage)) (and (soda)))是什么
#t
eqlist 是什么
查找两个list标是否小相同
eqlist?需要多少个查询
九个
为什么是九个查询
下面是我们的解释
”每个参数都可能
——是空表
——是原子cons出的list表
——是list表cos出的list表
例如,当第一个参数可能是空表,第二个参数可以有三种情况,那么3乘3共九种情况。
用eqan?写函数 eqlist?
(define eqan?
(lambda (a1 a2)
(cond
((and (number? a1) (number? a2)) (= a1 a2))
((or (number? a1) (number? a2)) #f)
(else (eq? a1 a2)))))
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define eqlist?
(lambda (l1 l2)
(cond
((and (null? l1) (null? l2)) #t) ;case1:l1 null,l2 null
((and (null? l1) (atom? (car l2))) #f) ;case2:l1 null,car l2 atom
((null? l1) #f) ;case3:l1 null,car l2 list
((and (atom? (car l1)) (null? l2)) #f) ;case4:car l1 atom, l2 null
((and (atom? (car l1)) (atom? (car l2))) ;case5:car l1 atom, car l2 atom
(and (eqan? (car l1) (car l2))
(eqlist? (cdr l1) (cdr l2))))
((atom? (car l1)) #f) ;case6:car l1 atom, car l2 list
((null? l2) #f) ;case7:car l1 list, l2 null
((atom? (car l2)) #f) ;case8:car l1 list, car l2 atom
(else ;case9:car l1 list,car l2 list
(and (eqlist? (car l1) (car l2))
(eqlist? (cdr l1) (cdr l2)))))))
(eqlist? '(beef ((sausage)) (and (soda))) '(beef ((sausage)) (and (soda))))
DrRacket环境测试结果为
欢迎使用 DrRacket, 版本 5.1.3 [3m].
语言: 大; memory limit: 64 MB.
#t
>
第二个查询(atom? (car l2))OK吗
是的,第二个list不能为空,否则就是第一个查询条件了。
第三个查询为什么是(null? l1)
通过前两个查询知道,第一个参数是空表时,第二个参数既不是空表也不是第一个元素是原子的list表。如果(null? l1)是真,那么第二个参数必须是其中第一个元素是list表的一个list表。
判断真假:如果第一个参数是(),eqlist?得到#t对吗
对。因为(eqlist? (quote ()) l2)为真,l2必须为空表。
这就是说(and (null? l1) (null? l2))和(or (null? l1) (null? l2))满足前三种查询的情况
是的。如果第一个查询是真,那么eqlist?得到#t;否则为#f。
重写eqlist?
(define eqan?
(lambda (a1 a2)
(cond
((and (number? a1) (number? a2)) (= a1 a2))
((or (number? a1) (number? a2)) #f)
(else (eq? a1 a2)))))
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define eqlist?
(lambda (l1 l2)
(cond
((and (null? l1) (null? l2)) #t) ;both are null
((or (null? l1) (null? l2) #f)) ;one is null
((and (atom? (car l1)) ;the following:none of l1,l2 is null
(atom? (car l2)))
(and (eqan? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2))))
((or (atom? (car l1)) ;one of cars is not atom
(atom? (car l2)))
#f)
(else (and (eqlist? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2)))))));both car are list
(eqlist? '(beef ((sausage)) (and (soda))) '(beef ((sausage)) (and (soda))))
DrRacket环境测试结果为
欢迎使用 DrRacket, 版本 5.1.3 [3m].
语言: 大; memory limit: 64 MB.
#t
>
什么是 S-expression表达式
原子或者由list构成的 S-expression表达式
为得到两个 S-expression表达式是否相同,equal?需要多少个查询
四个。第一个参数可能是空表或者list表构成的 S-expression表达式,第二个参数可能是空表或者list表构成的 S-expression表达式。
写出函数equal?
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define equal?
(lambda (s1 s2)
(cond
((and (atom? s1) (atom? s2)) (eqan? s1 s2));recurr terminating condtion,both are atom
((atom? s1) #f)
((atom? s2) #f)
(else (eqlist? s1 s2)))));both are list(include null list)
第二个问题为什么是(atom? s1)
如果为真,我们知道第一个参数是atom原子,第二个参数是list表。
第二个问题为什么是(atom? s2)
到第三个查询时,我们知道第一个参数不是atom原子,所以我们唯一需要区分的时第二个参数数是否是atom原子。第一个参数必然是一个list。
我们可以把第二个和第三个查询写成这样吗
(or (atom? s1) (atom? s2))
当然
简化equal?
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define equal?
(lambda (s1 s2)
(cond
((and (atom? s1) (atom? s2)) (eqan? s1 s2));recurr terminating condtion,both are atom
((or (atom? s1) (atom? s2)) #f);one is atom
(else (eqlist? s1 s2)))));both are list(include null list)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
第六戒
仅当函数正确后再简化
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
下面是把表lat替换为 S-expression表达式把a替换为任何 S-expression表达式后得到的新的rember
(define rember
(lambda (s l)
(cond
((null? l) (quote ()))
((atom? (car l))
(cond
((equal? s (car l)) (cdr l))
(else (cons (car l) (member s (cdr l))))))
(else (cond
((equal? s (car l)) (cdr l))
(else (cons (carl) (member s (cdr l)))))))))
可以简化吗
当然
(define rember
(lambda (s l)
(cond
((null? l) (quote()))
(cond
((equal? s (car l)) (cdr l))
(else (cons (car l) (rember s (cdr l))))))))
笔记:这个 S-expression表达式的rember有问题。如果(car l)本身不等于s但是l的成员或者l的成员的成员等等含有s的话那岂不是条过去了?
rember是一个"star"函数吗
不是
为什么
因为rember仅仅递归l的cdr
rember还能被简化吗
能,内层的(cond ...)可以提到外边的conde中。
做做看
(define rember
(lambda (s l)
(cond
((null? l) (quote()))
((equal? s (car l)) (cdr l))
(else (cons (car l) (rember s (cdr l)))))))
这个能正常工作么
当然,所有的分支和递归和化简之前一样。
化简 insertL*
不能。在查询(eq? (car l) old)我们必须知道(car l)是否是atom原子。
当函数设计的正确,我们就能够更好的思考它们。
而这比起错误的函数节约时间。
所有用eq?和=的地方和广义eq?都可以用函数equal?吗
不能。eqan?的地方就不能,其它的都可以。实际上,不考虑eqan?例子的细节,就是我们的假设。
the little schemer 笔记(5)的更多相关文章
- the little schemer 笔记(0)
the little schemer 笔记 Z.X.L 2012年08月13日 五项规则 car的规则car只对非空列表有定义. cdr的规则cdr只对非空列表有定义.任何非空列表的cdr是另外一个列 ...
- the little schemer 笔记(10)
第十章 What Is the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...
- the little schemer 笔记(3)
第三章 cons the magnificent (rember a lat)是什么,其中a是mint,lat是(lamb chops and mint jelly) (lamb chops and ...
- the little schemer 笔记(10.1)
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainla ...
- the little schemer 笔记(9)
第九章 ...and Again, and Again, and, Again, ... 你想来点鱼子酱吗? 那就去找它吧. (looking a lat)是什么,其中a是 caviar, lat是( ...
- the little schemer 笔记(8)
第八章 lambda the ultimate 还记得我们第五章末的rember和insertL吗 我们用equal?替换了eq? 你能用你eq?或者equal?写一个函数rember-f吗 还不能, ...
- the little schemer 笔记(7)
第七章 Friends and Relations 这是一个set集合吗 (apple peaches apple plum) 不是,apple出现了不止一次 (set? lat) 是真还是假,其中l ...
- the little schemer 笔记(6)
第六章 Shadows 1 是算术表达式吗 是 3 是算术表达式吗 是的 1+3 是算术表达式吗 是的 1+3×4 是算术表达式吗 当然是 cookie 是算术表达式吗 是啊,你需要来一块吗 e那么 ...
- the little schemer 笔记(4)
第四章 numbers games 14 是原子吗 是的,数都是原子 (atom? n) 是真还是假,其中n是14 真,14 是原子 -3是数吗 是的,不过我们暂不考虑负数 3.14159是数吗 是的 ...
随机推荐
- docker compose环境搭建
概述 Docker Compose提供一个简单的基于YAML配置语言.用于描写叙述和组装多容器的分布式应用. 使用docker定义和执行复杂的应用.使用compose,能够在一个文件中,定义多容器的应 ...
- fruitstrap 安装.app文件
1. 下载ipa的ios文件然后解压成.app的文件 2. 进入fruitstrap文件夹,copy .app文件到fruitstrap文件夹中 执行./fruitstrap -b umetrip.a ...
- adb pull 与 push
adb pull <remote> <local> Copies a specified file from an emulator/device instance to yo ...
- CentOS7虚拟机桥接设置及问题
转载请注明出处:jiq•钦's technical Blog 今天在VMWare WorkStation9中安装了CentOS7虚拟机. 虚拟机与宿主机网络连接有三种方式:桥接模式.NAT模式和Ho ...
- YTUOJ-推断字符串是否为回文
题目描写叙述 编敲代码,推断输入的一个字符串是否为回文.若是则输出"Yes",否则输出"No".所谓回文是指順读和倒读都是一样的字符串. 输入 输出 例子输入 ...
- NullpointerException真的一定要被预防?
毫无疑问,空指针NullpointerException是我们最常遇到异常,没有之一! 在刚进入编程职业时,我想,大部分进入的同学肯定会受到前辈们的叮咛:一定要防止空指针,这是个低级错误.你们不是?好 ...
- locate和grep命令
这任然是一篇读书笔记,以下内容来源<linux命令速查手册>这本书. 1.locate命令 用文件名或者文件名的部分来搜索文件在系统中的位置.locate不搜索具体目录,而是搜索一个数据库 ...
- design.js
//模块式开发 var myNamespace = (function () { var myPrivateVar = 0; var myPrivateMethod = function (foo) ...
- asp.net core zipkin
微服务监控zipkin+asp.net core 0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 监控目录:微服务监控zipkin.skywalking以及日志ELK监控系列 一 ...
- 高性能框架gevent和gunicorn在web上的应用及性能测试
WSGI Server有哪些: 比如 Flask,webpy,Django.CherryPy 都带着 WSGI server .当然性能都不好,自带的web server 更多的是测试用途, 发布时则 ...