第五章 “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)的更多相关文章

  1. the little schemer 笔记(0)

    the little schemer 笔记 Z.X.L 2012年08月13日 五项规则 car的规则car只对非空列表有定义. cdr的规则cdr只对非空列表有定义.任何非空列表的cdr是另外一个列 ...

  2. the little schemer 笔记(10)

    第十章 What Is  the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...

  3. the little schemer 笔记(3)

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

  4. the little schemer 笔记(10.1)

    This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainla ...

  5. the little schemer 笔记(9)

    第九章 ...and Again, and Again, and, Again, ... 你想来点鱼子酱吗? 那就去找它吧. (looking a lat)是什么,其中a是 caviar, lat是( ...

  6. the little schemer 笔记(8)

    第八章 lambda the ultimate 还记得我们第五章末的rember和insertL吗 我们用equal?替换了eq? 你能用你eq?或者equal?写一个函数rember-f吗 还不能, ...

  7. the little schemer 笔记(7)

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

  8. the little schemer 笔记(6)

    第六章 Shadows 1 是算术表达式吗 是 3 是算术表达式吗 是的 1+3 是算术表达式吗 是的 1+3×4 是算术表达式吗 当然是 cookie 是算术表达式吗 是啊,你需要来一块吗 e那么 ...

  9. the little schemer 笔记(4)

    第四章 numbers games 14 是原子吗 是的,数都是原子 (atom? n) 是真还是假,其中n是14 真,14 是原子 -3是数吗 是的,不过我们暂不考虑负数 3.14159是数吗 是的 ...

随机推荐

  1. [Other]来做一个微信打印机吧 -- 微信打印的设计思路參考

    项目源代码地址:https://github.com/callmewhy/why-wechat-printer 近期微信打印机小火了一把.比方印美团.747微信打印机,都是利用微信公共平台实现照片的打 ...

  2. Java集合框架:Arrays工具类

    java.util.Arrays类能方便地操作数组,它提供的方法都是静态的.整个Arrays工具类的实现有3000+行.可是归纳总结一下可知它有下面功能(9个): 1. asList 定义: @Saf ...

  3. GIF Movie Gear逆向实战+注册代码+补丁

    GIF Movie Gear逆向实战+注册代码+补丁 准备 我是在windows 8.1 x64上进行的操作.有不足之处,还望大虾指出. 获取资源 网站下载:http://www.gamani.com ...

  4. OpenStack源码系列---nova-compute

    nova-compute运行的节点为计算节点,虚拟机运行于计算节点上.例如对于创建虚拟机请求,nova-api接收到客户端请求后,经过nova-scheduler调度器调度,再将请求发送给某个选定的n ...

  5. openssl 再爆惊天漏洞及紧急修复指南

    openssl 又摊上大事了,2014年6月5日,SSL/TLS Man-in-the-Middle Vulnerability 该漏洞使得攻击者能够拦截恶意中间节点加密和解密数据.同一时候强迫使用弱 ...

  6. 云打印-Beta-凡事预则立

    凡事预则立 课程名称:软件工程1916|W(福州大学) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标:Beta冲刺 团队队员 队员学号 队员姓名 个人博客地址 备注 221600 ...

  7. git push & git pull 推送/拉取指定分支

    https://blog.csdn.net/litianze99/article/details/52452521

  8. 浏览器和服务器 对post get请求 url长度限制

    1. URL长度限制 2. Post数据的长度限制 3. Cookie的长度限制 1. GET  URL长度限制 在Http1.1协议中并没有提出针对URL的长度进行限制,RFC协议里面是这样描述的, ...

  9. Hadoop MapReduce两种架构 以及 YARN

    一.MRv1 Master - Slave 模式 存在JobTracker单点失败的问题,在YARN得到了解决. 主要包含4部分:JobTracker,TaskTracker,Task,Client ...

  10. flywaydb and sql server

    https://flywaydb.org/documentation/database/sqlserver How Flyway works https://flywaydb.org/getstart ...