过程作为黑箱抽象.ppt
《过程作为黑箱抽象.ppt》由会员分享,可在线阅读,更多相关《过程作为黑箱抽象.ppt(33页珍藏版)》请在三一办公上搜索。
1、过程作为黑箱抽象,sqrt程序的分解过程:这里的关键问题是,分解中的每一个过程完成了一件可以标明的工作,这使它们可以被用作定义其他过程的模块。我们可以将square看做一个黑箱,根本无须关注该过程是如何计算出结果的。更进一步,在相应过程还没有写好之前,我们可以只关心square这个名字,把它当做这个过程的抽象,在这个抽象层次上任何能计算出平方的过程都可以用。,过程作为黑箱抽象,可就是说,在只考虑过程的返回值时,下面两个过程应是不可区分的:(define(square x)(*x x)(define(square x)(exp(double(log x)(define(double x)(+x
2、x)可见一个过程定义应该能隐藏起某些细节,使得过程使用者可能不必自己去写这些过程,而是从其他程序员那里作为黑箱接受过来。并且在使用时应该不需要去弄清楚它是如何实现的。,过程作为黑箱抽象,局部名:过程用户不必关心实现细节之一就是过程里面的形式参数的名字,如(define(square y)(*y y)(define(square x)(*x x)这两个过程应该是无法区分的。形式参数的具体名字是什么,完全没有关系,这样的名字称为约束变量,一个过程的定义约束了它的所有形式参数。如果在一个完整的过程定义里将某个约束变量同一换名(注意不要跟其他形参名一样,实际上过程的定义也不允许有相同的形参名),这一过
3、程定义的意义将不会改变。不被约束的变量称为自由的。一个名字的定义被约束于的那一集表达式称为这个名字的作用域被声明为这个过程的形式参数的那些约束变量,就以这个过程体作为他们的作用域,过程作为黑箱抽象,内部定义和块结构:我们再来回顾前面的sqrt程序,其由几个相互分离的程序组成,问题是这组程序只有sqrt对用户是重要的,其它过程则会带来干扰。因此我们希望能够将这种子过程局部化,将它们隐藏到sqrt的里面。为使这种方式可能,我们要允许一个过程里面带有一些内部定义,使它们是局部于这一过程的。如:,过程作为黑箱抽象,平方根程序的内部定义表示:(define(sqrt x)(define(good-eno
4、ugh?guess x)(abs(-(square guess)x)0.001)(define(improve guess x)(average guess(/x guess)(define(sqrt-iter guess x)(if(good-enough?guess x)guess(sqrt-iter(improve guess x)x)(sqrt-iter 1.0 x)这种嵌套的定义称为块结构。,过程作为黑箱抽象,平方根程序的内部定义表示:分析上面的过程一种更好的想法是,没有必要显示的把x在内部过程中传来传去了,既然它们都在x的作用域里,我们可以直接给出如下定义:(define(sqrt
5、 x)(define(good-enough?guess)(abs(-(square guess)x)0.001)(define(improve guess)(average guess(/x guess)(define(sqrt-iter guess)(if(good-enough?guess)guess(sqrt-iter(improve guess)(sqrt-iter 1.0)这种方式叫做词法作用域。,线性的递归和迭代,考虑阶乘函数:(define(factorial n)(if(=n 1)1(*n(factorial(-n 1)我们利用代换模型,观看其求值的行为如图:,递归和迭代,计
6、算阶乘函数的不同的观点:(define(factorial n)(fact-iter 1 1 n)(define(fact-iter product counter max-count)(if(counter max-count)product(fact-iter(*counter product)(+counter 1)max-count),递归和迭代,计算阶乘函数的两种不同方法的比较:第一个过程中,代换模型揭示出一种先逐步展开而后收缩的形状,展开阶段里,构造起一个推迟操作所形成的链条(如前面的乘法链条),收缩阶段表现为这些运算的实际执行。这种由一个推迟执行的运算链条刻画的计算过程,称为一个
7、递归计算过程与之相对应,第二个计算过程里并没有任何增长或收缩。对任何一个n,计算过程的每一步,我们需要保存轨迹里,所有的东西就是变量的当前值,我们称这种过程为一个迭代计算过程。一般来说,迭代计算过程就是那种其状态可以用固定数目的状态变量描述的计算过程;同时还存在一套固定的规则,描述了计算过程在状态转换时,变量的更新方式。注意:不要混淆递归计算过程和递归过程的概念。递归过程是一个语法形式上的事实,说明一个过程定义中直接或间接引用了该过程本身。所以我们可以有如下陈述:一个递归过程将产生出一个迭代的计算过程。这是由于scheme中使用了一种称为尾递归的编译技术。,递归和迭代,树形递归:计算斐波那契数
8、列:(define(fib n)(cond(=n 0)0)(=n 1)1)(else(+(fib(-n 1)(fib(-n 2)考虑(fib 5)的计算过程:可以证明计算步骤相对于n是指数的这是一种很糟糕的计算过程。一般说,树形递归计算过程所需的步骤数正比与书中的结点数,空间需求正比于树的最大深度。,递归和迭代,计算斐波那契数列的迭代过程:(define(fib n)(fib-iter 1 0 n)(define(fib-iter a b count)(if(=count 0)b(fib-iter(+a b)a(-count 1)所需的步骤数相对于n是线性的但我们也不应作出结论说递归计算过程根
9、本没用。相反递归计算过程很自然,往往就是算法的直接翻译,能帮助我们理解和设计程序,而要规划出迭代过程,就不那么明显了。,实例研究:数的求幂,问题描述:计算出bn的值,我们有递归定义:bn=b*bn-1 b0=1直接翻译如下:(define(expt b n)(if(=n 0)1(*b(expt b(-n 1)这是一个线性递归计算过程,需要O(n)步和O(n)空间,实例研究:数的求幂,等价的线性迭代过程如下:(define(expt b n)(expt-iter b n 1)(define(expt-iter b counter product)(if(=counter 0)product(ex
10、pt-iter b(-counter 1)(*b product)需要O(n)步和O(1)空间,实例研究:数的求幂,算法的改进:我们可以通过连续求平方,以更少的步骤完成乘幂的计算。如:b2=b*b b4=b2*b2 b8=b4*b4 三次乘法就可以把b8算出来,而开始的算法主要计算7次乘法。(define(fast-expt b n)(cond(=n 0)1)(even?n)(square(fast-expt b(/n 2)(else(*b(fast-expt b(-n 1)even?是检测一个整数是否是偶数的谓词(define(even?n)(=(remainder n 2)0)这是一个递归
11、计算过程,该过程的增长阶为O(logn)给出该过程相应的迭代算法?,用高阶函数做抽象,如果将过程限制为只能以数作为参数,那也会严重地限制我们建立抽象的能力。经常有一些同样的程序设计模式能用于若干不同的过程。为了把这种模式描述为相应的概念,我们就需要构造出这样的过程,让他们以过程作为参数,或者以过程作为返回值。这类能操作过程的过程称为高阶过程,用高阶函数做抽象,过程作为参数:考虑下面3个过程:1.计算从a到b的各整数之和:(define(sum-integers a b)(if(a b)0(+a(sum-integers(+a 1)b)2.计算给定范围内的整数的立方之和:(define(sum-
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 过程 作为 黑箱 抽象

链接地址:https://www.31ppt.com/p-6490026.html