SICP第一章学习笔记

这不是简单得教授lisp的方言scheme如何使用的一本书,它以scheme作为工具来介绍模块化和黑盒抽象等一些软件工程方面的知识。
本书的在第一章开篇的程序设计的基本元素中提到,
    每一种强有力的语言都为此提供了三种机制:
        基本表达形式,用于表示语言所关心的最简单的个体
        组合的方法,从较简单的东西出发构造出复合的元素
        抽象的方法,为公共的模式命名,建立抽象,而后直接在抽象的层次上工作
而后的前三章基本是围绕这三种机制展开的,主要告诉我们构建程序的一些基本准则,以及一些使用方法,如消息传递技术等等。

第一章 构造过程抽象(Building Abstractions with Procedures)
    程序员在为windows构建应用程序时可以使用微软提供的接口,编写C++程序时可以调用标准库中的100多个算法,构建大型系统时可以使用其他程序员设计的函数过程等等。我们只需要知道这个过程的功能,便可以轻松得享受这个过程带来的便捷。也就是说只需要知道过程传入什么类型的参数,可以得到什么样的结果,并不需要知道其实现的细节,这也降低了系统构建的复杂度。也就是过程抽象。一些过程可能共享着一套公共模式,将这种模式抽象出来,实现为高阶函数来表述计算的一般性过程。同时,提取公共模式,也是设计模式里面模板方法的根本理论基础。除提取公共模式外,还可以通过复合,条件以及参数的使用将一些过程组合起来,形成复合的过程。
    过程的实现中,可以进行内部定义,这种将辅助过程局部化来隐藏它们的方法,也可以降低构建的复杂度。而利用一种称为递归的方式,可以在过程的定义中直接或间接得引用该过程本身。
    本章中Scheme涉及语法:基本表达式(前缀表示),define定义,cond条件表达式,基本谓词,and or not逻辑复合运算符,lambda构造过程,let创建局部变量,newline和display

    组合式的求值:首先求值该组合式的各个子表达式。然后将作为最左表达式(运算符)的值的那个过程应用于相应的实际参数,所谓实际参数也就是其他子表达式(运算对象)的值。如果子表达式也是组合式,则对这个子表达式执行同样的求值过程。也就是说求值过程是递归的。
环境所扮演的角色就是用于确定表达式中各个符号的意义。第三章将详细介绍环境
    过程应用的代换模型:正则式求值(完全展开而后归约),应用式求值(先求值参数而后应用)
    各种不同类型的表达式(每种有着与之相关联的求值规则)组成了程序设计语言的语法形式
      语法的糖衣是一种特殊的表示式,它为完全可以采用统一形式描述的东西给出的另一种表面结构,在程序的解释过程中会被解释为其他等价的表达式,然后进行求值
过程作为黑箱抽象
    过程抽象:作为识别基本行为和消除不相关的和繁琐的细节的过程,允许设计师专注于解决一个问题的考虑有关细节而不考虑不相关的较低级别的细节。过程抽象使得实现相同功能的过程可以重复使用。
    其中,过程的形式参量被称作约束变量,它们的作用域就是这个过程的体。
过程的定义中:
    允许一个过程里带有一些内部定义,使它们是局部于这一过程。这种嵌套的定义称为块结构。
    可以将外部定义的过程中的形式参量作为内部定义中的自由变量(称为词法作用域:要求过程中的自由变量实际引用外围过程定义中所出现的约束,即在定义笨过程的环境中去寻找它们)

线性递归:
    递归计算过程:执行过程中构造一个推迟进行的操作所形成的链条(实现过程需要使用堆栈)
    迭代计算过程(尾递归):状态可以用固定数目的状态变量描述的计算过程,不会导致一般递归的效率低下问题。
树形递归:
    递归次数呈指数级增加

高阶函数做抽象
    高阶函数:以过程作为参数,或者以过程作为返回值
    许多的过程可能共享着一套公共模式,可以将这种模式抽象出来,实现为高阶函数来表述计算的一般性过程。有了这个高阶过程,就可以用它作为基本构件,去形式化其他概念。


    程序设计语言总会对计算元素的可能使用方式强加上某些限制。带有最少限制的元素被称为具有第一级的状态。第一级元素的某些“特权”包括:可以用变量命名、可以提供给过程作为参量、可以由过程作为结果返回、可以包含在数据结构中







换零钱方式
    将总数为a的现金换成n种硬币的不同方式的数目等于
        将现金数a换成除第一个硬币之外的所有其他硬币的不同方式数目 + 将现金数a-d换成所有种类的硬币的不同方式数目,其中d是第一种硬币的币值
    统计总数目时
        如果a就是0,应该算作是有1种换零钱的方式。
        如果a小于0,应该算作是有0种换零钱的方式。
        如果n是0,应该算作是有0种换零钱的方式。
    产生一个树形的递归计算过程。
快速求冪 快速求斐波那契数
    求b的n次方
       若n是偶数,则b的n次方等于b的n/2次方的平方
       若n是奇数,则b的n次方等于b乘以b的n-1次方
       (判断奇偶数:求余)
    快速求第n个斐波那契数O(lgn)
       Tpq是对偶(a,b)按照a=bq+aq+ap,b=bp+aq规则的变换,而第n个斐波那契数的求解就是将变换T01的n次方应用于对偶(1,0)产生的。
       如果应用变换Tpq两次,其效果等同于应用同样形式的一次变换Tp`q`,其中p`=p*p+q*q,q`=2*p*q+q*q
       若n是偶数,则a b p` q` n/2
       若n是奇数,则bq+aq+ap bp+aq p q n-1
       当n等于0时,返回b
最大公约数
    欧几里算法
    根据定理如果欧几里得算法需要用k步计算出一对整数的GCD,那么这对数中较小的那个数必然大于或者等于第k个斐波那契数,可知算法的增长阶为O(lgn)
素数检测
 1、寻找因子:如果n不是素数,它必然有一个小于等于n的1/2次方的因子
 2、费马检查:O(lgn),保证概率上正确
    费马小定理:如果n是一个素数,a是小于n的任意正整数,那么a的n次方与a模n同余
    随机选取一个a进行计算,如果不同余说明不是素数,如果同余说明是素数的机会很大。检测的a值越多,就越增加对有关结果的信心。
 3、MillerRabin检查(此方法不会被欺骗)
    如果n是素数,a是任意小于n的整数,则a的(n-1)次冪与1模n同余。在求冪过程中的平方步骤时,检查是否遇到了“1取模n的非平凡根”。如果遇到,那么n就不是素数。

找出函数零点:
    1、通过区间折半寻找方程的根:如果对于给定点a和b有f(a)<0<f(b),那么连续函数f在a和b之间必然有一个零点
    2、牛顿法求函数零点:
           如果g(x)是一个可微函数,那么方程g(x)=0的一个解就是函数f(x)的一个不动点,其中f(x)=x-g(x)/Dg(x)
           通过搜寻f的不动点的方式去逼近g(x)=0的解。Dg(x)=(g(x+dx)-g(x))/dx
       牛顿法将函数零点问题转换为函数不动点问题
找到函数的不动点:
    如果x满足方程f(x)=x,则称x为函数f的不动点
    1、从某个初始猜测出发,反复应用f(x),f(f(x)),f(f(f(x))),,,,直到值的变化不大时,就可以找到一个不动点
    2、取逼进一个解的一系列值的平均值的方法,是一种称为平均阻尼的技术。(x+f(x))/2

 举例:求平方根问题。已知x求y,使得y*y=x
    设g(y)=y*y-x,令g(y)=0
         找出函数零点的第一个方法:不适用,因为不存在a和b使g(a)<0<g(b)
             第二个方法:f(y)=y-g(y)/Dg(y)=(y+x/y)/2,然后求f(y)的不动点,用不动点的两种方法都可以
    设f(y)=x/y,求f(y)=y时的值
         找到函数的不动点的第一个方法:不适用,引起振荡
             第二个方法:不断求y与f(y)的平均值
平滑一个函数
    如果f是一个函数,dx是某个很小的数值,那么f的平滑也是一个函数,它在点x的值就是f(x-dx),f(x)和f(x+dx)的平均值
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值