这章让我明白了原来自然数的定义本来就是个递归的过程。

我们通常用枚举的方式引出自然数的定义:0,1,2,3,等等(etc).最后的等等是什么意思?唯一能把等等从描述自然数的枚举方法中去除的方法是自引用,第一种尝试是:

0 is a natural number. 
If n is a natural number, then one more than n is one, too.

虽然这种描述并不是十分严格,但对于scheme格式的数据定义来说,他是一个很好的开始:

natural-number(自然数是以下2者之一

1。0

2.(add1 n) 如果n个自然数

0是第一个自然数

(add1 0)是下一个,接着就明显了:

(add1 (add1 0))

(add1 (add1 (add1 0)))

这些例子让我们想到了表的构造过程,我们从empty出发,通过cons连接更多的元素,构造出表。现在我们从0出发,通过(不断地)使用add1加上1,构造出自然数。

处理自然数的函数必须能够提取构造自然数时所使用的数,就像处理表的函数能够提取cons结构中的元素一样,执行这种提取操作的被称为sub1,它的运算规则是:

(sub1 (add1 n) )= n

它与cdr操作的运算规则类似:

(cdr (cons a-value a-list))= a-list

习题11.2.1:设计一个函数repeat,该函数读入一个自然数n个一个符号,返回包含n个符号的表:

;; repeat : natural-number -> list-of-symbols
(define (repeat n a-symbol)
(cond
[(zero? n) empty]
[else (cons a-symbol (repeat (sub1 n) a-symbol))])) ;; Examples
(repeat 'doll) "should be" empty
(repeat 'rocket) "should be" (cons 'rocket (cons 'rocket empty))

习题11.2.2:

Develop the function tabulate-f, which tabulates the values of

;; f : number  ->  number
(define (f x)
(+ (* 3 (* x x))
(+ (* -6 x)
-1)))

for some natural numbers. Specifically, it consumes a natural number n and produces a list of n posns. The first one combines n with (f n), the second one n-1 with (f n-1), etc.

设计函数,把函数f应用于一些由自然数值组成的表,其中f是上面的函数。

具体地说,函数读取自然数n,返回有n个posn结构体组成表,表的第一个元素是点(n (f n)),第二个为(n-1 (f n-1)),以此类推。

;; a list-of-posns is either:
;; - empty
;; - (cons posn list-of-posns) ;; f : number -> number
(define (f x)
(+ (* (* x x))
(+ (* - x)
-))) ;; tabulate-f : number -> list-of-posns
;; produces a list of posns of length n. Each
;; posn's x coordinate is a number, from 0 to n, and each
;; posn's y coordinate is the result of f on the same posn's
;; x coordinate. #|
;; TEMPLATE
(define (tabulate-f n)
(cond
[(zero? n) ...]
[else (tabulate-f (sub1 n)) ...]))
|# (define (tabulate-f n)
(cond
[(zero? n) empty]
[else (cons (make-posn n (f n))
(tabulate-f (sub1 n)))])) ;; EXAMPLES AS TESTS
(tabulate-f ) "should be" empty
(tabulate-f ) "should be"
(cons (make-posn )
(cons (make-posn )
(cons (make-posn -)
(cons (make-posn -)
empty))))

11.2.4

Lists may contain lists that contain lists and so on. Here is a data definition that takes this idea to an extreme:

deep-list is either

  1. s where s is some symbol or

  2. (cons dl empty), where dl is a deep list.

Develop the function depth, which consumes a deep list and determines how many times cons was used to construct it.

Develop the function make-deep, which consumes a symbol s and a natural number and produces a deep list containing s and constructed with nconses.

表的成员也可以是表,可以嵌套多层,下面就是这种思想的一个极端定义:

deep-list深层表示下列之一:

1.s其中s是symbol

2. (cons dl emtpy) dl是深层表。

设计函数depth,该函数读取一个深层表,测定这个表用了多少次cons来构成。设计函数make-deep,该函数读取符号s和自然数n,

返回包含s,使用n次cons构造的表。

;; depth : deep-list -> natural-number
;; counts the number of cons's used to create this deep list.
;depth:deep-list->number
(define (depth a-dl)
(cond
[(symbol? a-dl) ]
[else (+ (depth (car a-dl))) ]
)) (depth 'bottom) "should be" 0
(depth (cons (cons (cons (cons 'bottom empty) empty) empty) empty)) "should be" 4
(define (make-deep n s)
(cond
[(zero? n) s]
[else (cons (make-deep (sub1 n) s) empty)])) (make-deep 'bottom) "should be" 'bottom
(make-deep 'bottom) "should be"
(cons (cons (cons (cons 'bottom empty) empty) empty) empty)
DRracekt输出:'((((bottom))))
可以看到,很直观的表示4层嵌套。

自然数的另一种数据定义:

自然数(>=20)是系列之一:

1.20

2.(add 1 n)如果n是自然数。

说白了第一种定义时减法,第二种定义时加法。

计算从20(不包括20)到n(包括n)的乘积:

 ;计算n*(n-)...*
(define (product-from- n-above-)
(cond
[(= n-above- ) ]
[else (* n-above- (product-from- (sub1 n-above-)) )]
))
(product-from- ) ;462

《how to design programs》第11章自然数的更多相关文章

  1. 《how to design programs》12章函数复合

    我们写代码时要学会适应辅助函数.作者提出了一个问题,如何对一个表排序.排序函数读取一个表,产生另一个表.排序函数的合约和用途如下: (sort empty) ;; expected value: em ...

  2. 《how to design programs》15章 相互引用的数据定义

    由结构体组成的表与结构体中的表. 在用追溯形式建立家家谱树时,我们通常从某个后代除法,依次处理它的父母,组父母等.而构建树时,我们会不断添加谁是谁的孩子,而不是写出谁是谁的父母,从而建立一颗后代家谱树 ...

  3. 《how to design programs》14章 再论自引用数据

    这是一个家族谱: ;child(define-struct child (father mother name date eyes)) #lang racket ;child (define-stru ...

  4. 《how to design programs》13章用list构造表

    使用cons构造一个包含多个元素的表十分麻烦,因此scheme提供了list操作,该操作接受任意量的值作为输入以创建一个表,下面是扩展的语法: <prm>=list 扩展的scheme值的 ...

  5. 读《编写可维护的JavaScript》第11章总结

    这周也是拿到了同程的offer,从此走上了前端之路!感谢我的贵人们.再次纪念一下~! 第11章 不是你的对象不要动 11.1 什么是你的 你的对象:当你的代码创建了这些对象或者你有职责维护其他人的代码 ...

  6. 第11章 Windows线程池(1)_传统的Windows线程池

    第11章 Windows线程池 11.1 传统的Windows线程池及API (1)线程池中的几种底层线程 ①可变数量的长任务线程:WT_EXECUTELONGFUNCTION ②Timer线程:调用 ...

  7. 《TCP/IP详解卷1:协议》第11章 UDP:用户数据报协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  8. java JDK8 学习笔记——第11章 线程和并行API

    第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...

  9. 高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群

    高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群 libnet软件包<-依赖-heartbeat(包含ldirectord插件(需要perl-MailTools的rpm包)) l ...

随机推荐

  1. 关于google的C++ coding style

    大家都知道google的开源项目有很多,不过我观察过一些开源项目,觉得代码质量就是这家最好了.这些“教条”式规定的背后是是来自于常年工程经验积累上的理性思考. 为什么好?主要有以下几点: 1.规范,就 ...

  2. Android添加横线和竖线分割界面

    竖线 <View       android:layout_width="1dip"     android:layout_height="match_parent ...

  3. MCM1988 问题B_lingo_装货问题

    两辆平板车的装货问题有七种规格的包装箱要装到两辆铁路平板车上去包装箱的宽和高是一样的但厚度(t,以厘米计)及重量(,以公斤计)是不同的.下表给出了每种包装箱的厚度重量以及数量每辆平板车有10.2 米长 ...

  4. [转]jQuery EasyUI 扩展-- 主题(Themes)

    主题(Themes)允许您改变站点的外观和感观.使用主题可以节省设计的时间,让您腾出更多的时间进行开发.您也可以创建一个已有主题的子主题. 主题生成器(Theme Builder) jQuery UI ...

  5. 【转】ffmpeg中的sws_scale算法性能测试

    经常用到ffmpeg中的sws_scale来进行图像缩放和格式转换,该函数可以使用各种不同算法来对图像进行处理.以前一直很懒,懒得测试和甄别应该使用哪种算法,最近的工作时间,很多时候需要等待别人.忙里 ...

  6. hdu 5432 Pyramid Split(二分搜索)

    Problem Description Xiao Ming is a citizen who's good at playing,he has lot's of gold cones which ha ...

  7. pyqt menu子级方向例子学习

    代码和UI文件:http://yunpan.cn/QCkXbX8mnSNke(提取码:51e1) 图片如: 代码如下: from PyQt4 import QtCore,QtGui,Qt import ...

  8. Ant-进阶

    Ant的概念 可能有些读者并不连接什么是Ant以及入可使用它,但只要使用通过Linux系统得读者,应该知道make这个命令.当编译Linux内核及一些软件的源程序时,经常要用这个命令.Make命令其实 ...

  9. 设计模式13---设计模式之观察者模式(Observer)(行为型)

    1.场景模式抽象 订阅报纸的过程,如果报纸来了的时间不确定,那么订报纸的人如何知道呢?可以抽象为:当一个对象的状态发生改变的时候,如何让依赖他的所有对象得到通知,并进行相应的处理呢?生活中最常见的例子 ...

  10. 密码算法详解——AES

    0 AES简介 1997年1月2号,美国国家标准技术研究所宣布希望征集一个安全性能更高的加密算法(AES)[3],用以取代DES.我们知道DES的密钥长度是64 bits,但实际加解密中使用的有效长度 ...