第五章 “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. 性能问题案例02——sybase连接堵塞问题

    现象:近期现场反馈一个问题.系统在审批的时候,常常卡死.整个系统全然用不了,浏览器訪问处于loading的状态. 排查: 1.一般系统挂了首先想到内存问题,可是现象是loading,也就是说没有挂,线 ...

  2. ActionFilterAttribute之HtmlFilter,压缩HTML代码

    当开启这个过滤器后,最终生成的HTML代码将会被压缩一下,在流量很大的网站中,能减少带宽成本就减少一点,何乐而不为? [csharp] view plaincopy using System; usi ...

  3. SDOI2016R1(不是解题报告)

    话说洗澡的时候想了一堆要说的,坐到电脑前反而不知所措了-- 序章 听学长说他们都是省选一周前才停的课.然而我们这届--自聪哥韩大他们在省选两周前悄悄跑路后(据说班主任非常支持),信息小组内部一呼百应, ...

  4. VC++ 学习笔记(四):停止还是暂停这个系列

    我已经很久没有更新这个话题了,原因是多方面的,比如比较忙,比如我参与的项目不使用C++.最近因为需要在C#的客户端中调用第三方的C++API,又想起了这个话题.在跟公司里的C++方面专家聊过之后,我有 ...

  5. Mahout 0.5部署

    Mahout下载与安装 1.下载Mahout.到地址[1]可以找到镜像地址.我们下载Mahout 0.5.请将mahout-distribution-0.5.tar.gz和mahout-distrib ...

  6. 常用的sql命令

    1 mysql创建数据库 create database [database name]; 2 创建表 create table [table name]([first column name] [f ...

  7. Cooperating sequential processes》,这篇论文提出了大名鼎鼎的概念信号量,Java里面用于线程同步的wait/notify也是信号量的一种实现。

    闲话高并发的那些神话,看京东架构师如何把它拉下神坛 https://mp.weixin.qq.com/s/lAqn8CfSRta9iSvOR1Le6w

  8. jsp项目上传到服务器

    我们通过Myeclipse完成一个Java web项目时只能通过本地访问来查看,但是我们想把它上传到服务器上使用外网访问应该怎么做呢,首先肯定是要有一台服务器 个人调试项目试手的话我建议去买阿里云的云 ...

  9. 【Selenium】验证是否按照字母顺序排列, 不区分大小写

    验证是否按照字母顺序排列, 不区分大小写 for(int j=0;j<s.length-1;j++){ String temp1=s[j].toLowerCase(); String temp2 ...

  10. zoj 3204 Connect them(最小生成树)

    题意:裸最小生成树,主要是要按照字典序. 思路:模板 prim: #include<iostream> #include<stdio.h> #include<string ...