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?例子的细节,就是我们的假设。

posted @ 2019-01-21 10:20 史D芬周 阅读(...) 评论(...) 编辑 收藏

the little schemer 笔记(5)相关推荐

  1. the little schemer 笔记(3)

    第三章 cons the magnificent (rember a lat)是什么,其中a是mint,lat是(lamb chops and mint jelly) (lamb chops and ...

  2. the little schemer 笔记(7)

    第七章 Friends and Relations 这是一个set集合吗 (apple peaches apple plum) 不是,apple出现了不止一次 (set? lat) 是真还是假,其中l ...

  3. The Little Shemer笔记

    ;;预备函数 (define (atom? x)(and (not (pair? x))(not (null? x)))) (define (sub1 x)(- x 1)) (define (add1 ...

  4. 【读书笔记】知易行难,多实践

    前言: 其实,我不喜欢看书,只是喜欢找答案,想通过专业的解答来解决我生活的困惑.所以,我听了很多书,也看了很多书,但看完书,没有很多的实践,导致我并不很深入在很多时候. 分享读书笔记: <高效1 ...

  5. 【运维学习笔记】生命不息,搞事开始。。。

    001生命不息,搞事不止!!! 这段时间和hexesdesu搞了很多事情! 之前是机械硬盘和固态硬盘的测速,我就在那默默的看着他一个硬盘一个机械测来测去. 坐在他后面,每天都能看到这位萌萌的小男孩,各 ...

  6. SSAN 关系抽取 论文笔记

    20210621 https://zhuanlan.zhihu.com/p/353183322 [KG笔记]八.文档级(Document Level)关系抽取任务 共指id嵌入一样 但是实体嵌入的时候 ...

  7. pandas以前笔记

    # -*- coding: utf-8 -*- """ Created on Sat Jul 21 20:06:20 2018@author: heimi "& ...

  8. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  9. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

最新文章

  1. va_list和va_start和((A*)0)-a
  2. AI、ML 和数据工程 | InfoQ 趋势报告(2021 年)
  3. 条件随机场(CRF)和隐马尔科夫模型(HMM)最大区别在哪里?CRF的全局最优体现在哪里?
  4. linux子系统使用rstudio,Windows 10 Linux子系统 (wsl)学习手记
  5. 登录系统 提示框_实物资产管理软件操作手册(职员和系统用户)
  6. Linux下使用socket传输文件的C语言简单实现
  7. el-table文字超出隐藏;el-table表格文字一行展示,超出隐藏,多余的内容会在 hover时显示 ;
  8. DroidBox的环境搭建与使用(Android沙箱、未验证)
  9. 苹果全新10.2英寸iPad再爆实锤 或造成史上最乱的iPad产品线
  10. orcale建表,创建字段id使其自增
  11. Mac OSX x86 10.4.6 安装小记(1)
  12. java velocity js_JavaScript 模板引擎 Velocity.js_js
  13. VSFTPD 上传文件 200 227 553错误
  14. matlab fisher检验,FISHER线性判别MATLAB实现.doc
  15. 联创机房管理系统重连服务器失败,联创机房管理系统在CAD实验室应用探析.doc...
  16. 2023哈尔滨工业大学计算机考研信息汇总
  17. C#语言入门详解1-12
  18. 11.8号软基2.2.2
  19. expect 自动输入密码
  20. 柠萌影业三次冲刺IPO,爆款制造机的压力大爆了

热门文章

  1. 板绘教程|日漫风格插画,夸张与现实的意境
  2. flutter jsonEncode和jsonDecode,sharedpreferences存model数据
  3. php制作万年历的步骤_PHP制作万年历_php实例
  4. Boilsoft Video Splitter(视频无损分割)V8.1.4开心版 全网独一
  5. 前端实现pdf在线批注|画笔|添加文字|添加矩形|添加圆形|定制图形|缩放|撤销恢复|保存批注|下载等功能
  6. GCC总结、C语言关键字和运算符
  7. ZTE中兴-m3860模块指南
  8. 基于车牌颜色(仅限蓝色和黄色)的车牌定位(python+opencv实现)
  9. 机器学习实践:动物图片识别-1
  10. 吉首大学计算机专业宿舍,吉首大学宿舍条件,宿舍环境图片(10篇)