关于人对事物的认知主要有三个方面
- 将若干简单认识组合为一个复合知识,由此产生出各种复杂的认识。
- 将两个认识放在一起对照,不管他们如何简单或者复杂,在这样做时并不将它们合而为一。由此得到有关它们的相互关系的认识。
- 将有关认识与那些在实际中和它们同在的所有认识隔离开,这就是抽象,所有具有普遍性的认识都是这样得到的。
习题1.4
这道题一开始我并没有得出比较正确的答案,我认为的答案是将两个数进行一个绝对值的相加。实际上的正确答案应该是通过这样子的一个define来进行一个高阶函数的运算,接受多个数据并对他们进行运算,是“数据” 和过程的统一
习题1.5
写这道题之前我其实一直对正则序和应用序这两个玩意有点儿弄球不懂。在书上得出来的结果感觉是有限的。实际上正则序在小规模程序里面更容易被理解,它的做法实际上就是直接把问题展开,然后分布解决小的问题,这和早期的人工智能也有一定的相像之处。而应用序就有点儿像我们所说的暴力了,通过不断递归,一直到获得最终结果为止,实际上在应用的时候,应用序能够更容易被接受,我个人的观点认为可能是拆解问题所需要的模型和方法可能并不简单,有的时候在一定量级内应该是可以获得更好和快的结果的。这两者对于问题的求解不同的地方正是这道题的考核点。
(define (p) (p))
(define (test x y)
(if(= x 0)
0
y))
这行代码在执行的时候,如果代入的x = 0, y = p,如果通过正则序求解可以直接获得0这个结果,如果通过应用序求解就会递归成无限循环,其中逻辑请各位也去结合上文想想嘿嘿。
关于牛顿法求平方根的证明
比如说需要求的是2的平方根。
猜测是1,2/1=2, (2+1)/2 = 1.5;
1.5, 2/1.5 = 1.3333, (1.5 + 1.3333)/2 = 1.4167
1.4167, 2/1.4167 = 1.4118, (1.4118 + 1.4167) / 2 = 1.4142;
方法很粗暴简单,但是为什么可以这样子求解?
- 所求的X应为y的平方根
- x*x = y;
- y / x = x;
- (x+x)/2 = x;
得证。
并可由此延伸出牛顿法的立方根求法
- x*x*x = y;
- y / x / x = x;
- y / x / x + 2x / 3 = x;
得证。
习题1.6
这道题其实和1.5很相似,不需要再展开来说了,因为在lisp中cond函数是进行应用序求值的,它在这样子的一个函数中会对第三个参数进行循环调用使得最后进入一个不可跳出的死循环。
习题1.7
不难得出,因为牛顿法是通过求平均值来获得最后的结果的,所以基本不会获得一个精准的整数,所以在面对精度控制的问题上会出现问题,就如同10000的平方根是100,如果控制的精度卡死在0.000001的话,那么就会出现非常大的性能浪费,所以通过结果与前一个结果的比例关系来获得的话是相对来说比较简单而高性能的,不过必须要注意的就是除数为零的情况就是了。
习题1.8
已证明
习题1.9
第一个函数是递归的,第二个函数是迭代的。迭代和递归是不同的概念。递归会不断地调用本身进行运算,而迭代则是不断地进行求解获得结果,虽然可能会有重叠,但是在概念上面是有差别的。
尾递归
关于递归和迭代的差别,迭代所使用的内存空间是常数量级的,而递归则不一样。
简而言之如一下代码。
int recsum(int x)
{
if (x == 1) return x
else return x + recsum(x - 1)
}
看起来好像没有什么问题,在一开始的求解斐波那契数列的时候我们也曾经这样子写过,但是这样子的写法会炸。为什么?
recsum(5)
5 + recsum(4)
5 + (4 + recsum(3))
5 + (4 + (3 + recsum(2)))
5 + (4 + (3 + (2 + recsum(1))))
5 + (4 + (3 + (2 + 1)))
5 + (4 + (3 + 3))
5 + (4 + 6)
5 + 10
15
这就是这个函数运行的时候的内存占用情况, 问题就显而易见了。当我进入下一个步骤的时候,上一个步骤的内存占用量并没有能够删除掉,也就是说在这样子的递归环境下我不断为recsum这个函数申请内存地址,最后达到峰值才不断地回落,这样的一个过程中是可能会造成爆栈的。
尾递归是可以在常数量级内解决问题的递归。
简而言之就是,我不断更新原本的内存空间,而不是去进行重新申请。
int recsum(int x,int y)
{
if (!x)return y;
else return recsum(x-1, y + x);
}
习题1.13
我TM。。我就不该好奇先证这道题。。。
花了一个多小时的时间,都没有想通为什么最后查了一下才发现原来是条件缺失了,我并没有拿到所有的条件我@#!@¥@#!¥直接用数学归纳法可以求解出后半部分的内容,前半部分的内容则通过特定定理求出,下面是证明过程。