这书也算是必修吧,尤其是我这种非科班人员,还是应该抽时间尽量学习一下。大致翻过一遍,习题非常多,尽力吧。
##构造过程抽象
* 为了表述认知,每种语言都提供了三种机制:基本元素;组合方式;抽象方法。
* 前缀表示法,haskell中有学过,scheme中基本都是前缀表达,这使得表达式的可读性略微降低。
* 声明变量:`(#define name value)`,和C中的宏声明一致,声明函数:`(#define (func ( para1,para2...) ())`;
* 一般性求职规则是**树形累积**,其他的被称为**特殊形式**(如`define`语句)。
* Scheme中多项式求值遵从**代换模型**,即逐步将过程调用代换为对应的过程和变量。先展开后规约的成为**正则序求值**,否则被称为**应用序求值**。在Scala中,分别对应*Call By Name* 和 *Call By Value*。和Scala一样,Lisp也是默认遵从后者。
* 条件表达式:`cond`关键字,对应现代语言中的`switch`,`if`关键字,只能在非此即彼的情况下使用(换言之,没有`else if`)。
* 逻辑运算符:`and`, `or` 和 `not`.
###练习部分:
1.3:
```lisp
(define (sumMax2 x y z)
(if (= x (larger x y))
(+ x (larger y z))
(+ y (larger x z))))
(define (larger a b)
(if (> a b) a b)) (sumMax2 1 2 3)
``` 1.5 由于第二个参数是一个endless loop,如果对其做value展开,就会死掉,换句话说:如果死机就是应用序,否则是正则序。 * 牛顿迭代法求平方根
```lisp
(define (sqrt x)
(define (isGoodEnough guess)
(< (abs (- (* guess guess) x)) 0.001))
(define (improve guess)
(average guess (/ x guess)))
(define (sqrtIter guess)
(if (isGoodEnough guess)
guess
(improve guess)))
(sqrtIter 1.0)) (define (average x y)
(/ (+ x y) 2.0)) (define (abs x)
((if (> x 0) + -) x))
```
1.6 由于lisp是应用序优先的,因此
```lisp
new-if ( good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)
``` 的计算过程是先计算 `(good-enough? guess x)`,而下一步是计算`(sqrt-iter (improve guess x))`,换句话说,递归被无条件执行了,因此程序会陷入死循环。 * 过程的形式参数被称为“约束变量”,与之对应的成为“自由变量”,所谓**约束**,过程约束了形式参数。如果像上文一样把一些过程定义在某个过程内部,这个过程的形参就在所有的过程中共享,不必再次声明,这被称为“词法作用域”。有点类似类内部的私有函数。
* 尾递归与普通递归的区别:简单来说,尾递归可以被优化成迭代,对于lisp这种没有循环语句的语言,掌握尾递归是一项必备技能。非尾递归可能造成堆栈溢出,尾递归无此后患(现代C/C++的编译器也会自动优化尾递归)。 1.9 `a+b`展开为:` ++(--a+b)`,`+`运算需要再次展开,直到a=0,因此是递归计算过程;而后者展开为`(--a)+(++b)`,不需要伸展长度,因此是尾递归|迭代。 1.10 (A 1 10)=A(0 (A 1 9))=A(0 (A 0 A(1 8)))..A(...A(1 1))=$2^{10}$ (A 2 4)=A(1 (A 2 3))=A(1 (A 1 A(2 2)))...A(...A(2 1))=$2^{16}$ (A 3 3)=A(2 A(3 2))=A(2 A(2 A(3 1)))...=$2^{16}$ 根据上面的展开规律: (f n)=2n; (g n)=$2^n$ (h n)=$2^{2^n}=4^n$ * 树形展开,即递归的展开是一棵树,这个是比较常见的情况。书中举了著名的坑爹例子”斐波那契“,这个例子是有名的不适合使用递归计算的递归式。
$$f(n)=\begin{equation}
\begin{cases}
0, &n = 0\\
1, &n=1\\
f(n-1)+f(n-2), &n > 1\\
\end{cases}
\end{equation}
$$
[$\LaTeX$公式的命令都快不记得了,去查了半天ORZ] 如果想要转为迭代,用常规命令语言的思路:
```c
if(n==0)return 0;
if(n==1)return 1;
int pre=0;
int result=1;
int temp;
while(--n>0)
{
temp=result;
result=result+pre;
pre=temp;
}
return result;
```
显然,需要两个中间变量,循环结束的条件是次数。使用尾递归实现,因为不需要中间变量交换数据,所以所需变量少一个。 ```lisp
(define (f n)
(f-iter 0 1 n) (define (f-iter pre result count)
(if (= count 0)
b
(f-iter result (+pre result) (- count 1)))
)
```
你看,其实并不难,只要你会写循环…当然,尾递归要简洁很多。如果能够跳出命令式思维,直接想到尾递归写法,这函数式编程才能算入了门(好难= =)。 * 换零钱的例子。其实这是一个组合算法,总的组合次数=一定用了某个部件的次数+一定没用某个部件的次数。按着这个规律进行规约,最终退化到边界情况,问题解决。使用这种典型的分治式思维,写出的代码非常简洁。著名的快速排序也是一句话:快排的结果应该是把比某元素小的快排结果放在其前面,把比该元素大的结果放在后面,这个haskell只要两行,常被用来做广告,哈哈。 ```haskell
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
``` Lisp版:
```lisp
define (quicksort x)
(cond
((null? x) ‘())
(else (append
(quicksort (filter (lambda (y) (< y (car x))) (cdr x)))
(list (car x))
(quicksort (filter (lambda (y) (>= y (car x))) (cdr x)))))))
```
注:这个是从网上找的,我的lisp水平和这篇笔记的进度一致。 1.11
$$ f(n)=\begin{equation}
\begin{cases}
n,&n<3\\
f(n-1)+f(n-2)+f(n-3),&n \ge 3\\
\end{cases}
\end{equation}
$$ ```lisp
(define (f n)
(if (<= n 3)
n
(f-iter 1 2 3 n))) (define (f-iter ppre pre result count)
(if (<= count 3)
result
(f-iter pre
result
(+ (* 3 ppre) (* 2 pre) result)
(- count 1))))
```
1.12 帕斯卡三角形,把它当成一个下三角,从二维的角度来讲:
$$f(x,y)=\begin{equation}
\begin{cases}
1,& y=1 \text{ or } x=y\\
f(x-1,y-1)+f(x-1,y),&x>y \text{ and } y!=1\\
\end{cases}
\end{equation}
$$ ```lisp
(define (f x y)
(cond ((< x y) null)
((= y 1) 1)
((= x y) 1)
(else (+ (f (- x 1) (- y 1))
(f (- x 1) y)))))
```
1.13 纯数学题,这里就略过吧ORZ,我印象中上学的时候似乎证明过。 下面一部分是讲复杂度的,CLRS这里讲的很明白,略过。 * 求幂的题目。这题在面试题中倒是很常见,一个技巧
$$a^n=a^{n/2}*a^{n/2}$$
所以如果n是偶数,需要$\log{n}$次,是奇数就是$\log{n}+1$次。对应的代码段: ```lisp
(define (exp a n)
(define (even? n)
(= (remainder n 2) 0))
(cond (= (n 0) 1)
((even? n) (square (exp (/ n 2))))
(else (* a (exp a n-1)))))
```
显然,这里递归运算,下面描述对应的迭代,主要利用了公式:
$(a^{n/2})^2=(a^2)^{n/2}$,反向分解的思路:
$5^7=5^3*5^3*5=5^2*5*5^2*5*5$,显然,n是偶数,除以2,递归;n是奇数,减1,递归 ```lisp
(define (exp a n)
(define (square a) (* a a))
(define (even? n)
(= (remainder n 2) 0))
(define (exp-iter a n result)
(cond ((= n 0) result)
((even? n) (exp-iter (square a) (/ n 2) result))
(else (exp-iter a (- n 1) (* a result)))))
(exp-iter a n 1))
``` 1.17 好吧,这种题很适合做面试题,定义了乘法,倍乘和减半,实际上把上面的代码中相关的代换掉就可以了。其中`even?`需要用一些技巧,不过也不困难。 先到这里,这本书读的很慢…习题太多,每周抽一天时间学习吧。

SCIP读书笔记(1)的更多相关文章

  1. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  2. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  3. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  4. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  5. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  6. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

  7. LOMA280保险原理读书笔记

    LOMA是国际金融保险管理学院(Life Office Management Association)的英文简称.国际金融保险管理学院是一个保险和金融服务机构的国际组织,它的创建目的是为了促进信息交流 ...

  8. 《3D Math Primer for Graphics and Game Development》读书笔记2

    <3D Math Primer for Graphics and Game Development>读书笔记2 上一篇得到了"矩阵等价于变换后的基向量"这一结论. 本篇 ...

  9. 《3D Math Primer for Graphics and Game Development》读书笔记1

    <3D Math Primer for Graphics and Game Development>读书笔记1 本文是<3D Math Primer for Graphics and ...

随机推荐

  1. ANDROID_MARS学习笔记_S04_005_用sing-post向腾讯微博发一条信息

    一.代码流程 1.组织好sign-post需要的token,secrect 2.组织好发微博需要的信息 3.用sign-post进行签名 4.把签名结果从header中拿出来,转成entity,用ht ...

  2. 实现ImageView中两张图片重叠显示

    第一种XML配置 使用layer-list标签 <layer-list xmlns:android="http://schemas.android.com/apk/res/androi ...

  3. tar 解压命令

    1.tar.gz文件的解压 tar zxvf  *.tar.gz 2.bz2属性的解压 tar jxvf  *.bz2

  4. POJ_2914_Minimum_Cut_(Stoer_Wagner)

    描述 http://poj.org/problem?id=2914 求无向图中最小割. Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K T ...

  5. PHP中 magic_quotes_gpc 和 magic_quotes_runtime 区别及其反斜线转义问题

    php中关于反斜线转义: php中数据的魔法引用函数 magic_quotes_gpc  或 magic_quotes_runtime     设置为on时,当数据遇到 单引号' 和 双引号" ...

  6. hdoj 1047 Integer Inquiry

    Integer Inquiry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  7. 【BZOJ-1901】Dynamic Rankings 带修主席树

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7292  Solved: 3038[Su ...

  8. NOIP-2003 加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  9. 关于PHP程序员解决问题的能力

    这个话题老生长谈了,在面试中必然考核的能力中,我个人认为解决问题能力是排第一位的,比学习能力优先级更高.解决问题的能力既能看出程序员的思维能力,应变能力,探索能力等,又可以看出他的经验.如果解决问题能 ...

  10. MINA学习之体系介绍

    基于MINA应用程序结构图: 我们可以看出,MINA是应用程序(客户端或服务端)和底层基于TCP,UDP等通讯协议的网络层之间的粘合剂.而且各个模块之间是相互独立的,你只需要在MINA体 系基础上设计 ...