SICP练习1.16
在之前的学习中,我们学习了关于求幂的一系列算法;
比如求幂的递归算法,这个算法的体验和之前学习的阶乘的算法是差不多的;
一、求幂的递归算法实现
利用(expt b n)中n不断减小达到n=0时返回值为1为终止,
(if (= n 0)1(* b (expt b (- n 1))))
这样一个过程得到的代换模型如下:
(* b (* b (* b (...(* b (- n 1)))))) 此时的n为1,
这里需要理解递归的过程。二、求幂的迭代算法实现
利用一个计数器counter和一个乘积product,
计数器的初始值为n,不断减小到0,
其间乘积product的值为b和product相乘得到的值,
当计数器的值为0时,返回此时product的值,
(define (expt b n)(define (expt-iter b counter product)(if (= counter 0)product(expt-iter b(- counter 1)(* b product)))))三、快速求幂的算法实现
利用了一个公式,
当n为偶数的时候,b^n=(b^(n/2))^2,
b的n次方等于b的二分之n次方的平方,
于是有以下表达示:
(if (even? n)(square (fast-expt b (/ n 2)))
但是在遇到n是奇数的时候,
调用一个b乘以fast-expt,再在此时的n参数处减去一个1来实现,
(define (fast-expt b n)(if (even? n)(square (fast-expt b (/ n 2)))(else (* b (fast-expt b (- n 1))))))四、用迭代的方法来实现一个有快速求幂的算法实现
这就是本练习题了,
做这道题的时候读了好几遍没有读懂题,
其实一开始他就告诉我们要求,
“请定义一个过程,它能产生出一个按照迭代方式的求幂过程”
“其中使用一系列的求平方,就像fast-expt一样只用对数个步骤”
在看中文的时候有一个地方翻译有问题,
书上“一样”两个字放在了“fast-expt”的前面,照成了阅读困难,
英文为:
“Design a procedure that evolves an iterative exponentiation
process that uses successive squaring and uses a logarithmic
number of steps, as does fast-expt.”
其中提示了b^n=(b^(n/2))^2=(b^2)^(n/2)
还有一个提示是说在指数n和基数b以外,
还要有一个维持附加状态的变量a,并定义好状态的转变,
从一个状态到另一状态的转换时乘积ab^n不变。
第二个提示不好理解,应该说的时当a成为一个形参时,
在指数为单数和双数的过程中两个过程的实参不能互相影响,
要做到这一点,a也只能是一个形参(formal parameters),
而a在两种状态下都要传递实参(argument)进去,
初始的a为形参(formal parameters),
在这里也有另一个叫法“不变量(invariant quantity)”,
最后一个提示也最为关键,
“定义一个不变量,
要求它在状态之间保持不变,
这一技术是思考迭代算法设计问题时的一种非常强有力的方法。”
这句话值得细细品味,慢慢理解。
回到正题,
在fast-expt算法中有在n为双数的时候(square (fast-expt b (/ n 2)))
在改变成迭代算法的时候可以利用(b^(n/2))^2=(b^2)^(n/2)(fast-expt (square b) (/ n 2))
其理念为把b的“n/2”次方的平方,
变成了b的平方的“n/2”次方,
如此就完成了指数为双数时递归向迭代的转换;
要完成单数指数的计算,这时就要用到不变量a了,
在网上看到的思路为,
在迭代算法(fast-expt-iter)中引入如下形参(formal parameters):
index(指数)、base(底数)、a(不变量)
当指数为0时,返回值为0,
当指数为1时,返回值为a * base,
当指数为双数时,返回值为(fast-expt-iter (square base) (/ n 2) a)
当指数为单数时,且每次出现指数为单数时,
在过程中当时a这个形参的值就会是a * base,(else (fast-expt-iter base (- index 1) (* a base)))
最后应用过程并用实参进行取代形参如下(fast-expt-itxer b n 1)
尝试写代码2021年3月20日17:58
(define fast-expt(lambda (b n)(define fast-expt-iter(lambda (base index a)(cond ((= index 0) 1)((= index 1) (* a base))((even? index)(fast-expt-iter (square base)(/ index 2)a))(else (fast-expt-iter base(- index 1)(* a base))))))(define even?(lambda (x)(= (remainder x 2) 0)))(define square(lambda (x)(* x x)))(fast-expt-iter b n 1)))
SICP练习1.16相关推荐
- 实现手机来电铃声,通知铃声、警告铃声等音频定制化功能(三,多媒体扫描结果定制处理)
本篇博文主要是对MediaScanner中endFile方法的处理流程上的重构,以实现需求中的资源区域化定制.处理思路为首先扫描定制分区中的资源,在扫描系统分区下默认资源时判断定制分区西下是否已经存在 ...
- sqlserver错误码
错误 6,000 到 6,999 错误 严重性 是否记录事件 说明 6001 10 否 SHUTDOWN 正在等待 %d 个进程完成. 6004 10 否 用户没有执行此操作的权限. 6005 10 ...
- [books] - SICP 2nd edition
全名是: Structure and Interpretation of Computer Programs 中文名稱: 计算机程序的构造和解释 20131024 淘寶訂單 20131104 到手, ...
- 学习伯克利CS 61A课程(Structure and Interpretation of Computer Programs, SICP)的相关资源
有个叫做Teach Yourself Computer Science的网站[1]教如何自学计算机科学,关于Programming这个方向推荐了<Structure and Interpreta ...
- SICP(计算机程序构造与解释)学习笔记(lisp语言实现)
用的是这版本 由于逆天的语法,必须准确记清楚 目录 Scheme语法 递归与阶乘 1.递归与阶乘的区别 2.阶乘与递归的实例 阶乘的递归实现 阶乘的迭代实现 斐波那契数列的递归实现 1.3高阶过程实现 ...
- 计算机程序结构和解释,SICP 计算机程序的构造和解释
<SICP 计算机程序的构造和解释>由会员分享,可在线阅读,更多相关<SICP 计算机程序的构造和解释(5页珍藏版)>请在人人文库网上搜索. 1.SICP 计算机程序的构造和解 ...
- 《SICP》习题第3章(施工中)
本人做的SICP习题第3章,如有错误请指正,用的解释器是Racket 练习3.1 ;; 累加器 (define (make-accumulator initial)(lambda (x)(let (( ...
- UCB CS61A | SICP C1
Textbook (SICP for python) It's adapted from the legendary book ----<Structure and Interpretation ...
- Go 1.16 的这个新变化需要适应下:go get 和 go install 的变化
原文地址: Go 1.16 的这个新变化需要适应下:go get 和 go install 的变化 一直以来,go get 用于下载并安装 Go 包.命令等,而 go install 在 module ...
- Ubuntu 16.04 安装后修改屏幕分辨率(xrandr: Failed to get size of gamma for output default)
ubuntu 16.04 安装后分辨率只有一个选项 1024x768,使用 xrandr 命令出现错误: xrandr: Failed to get size of gamma for output ...
最新文章
- 上班第一天公司要你用Spring Boot 实现万能文件在线预览
- CVPR 2020 Oral | 旷视提出Circle Loss,革新深度特征学习范式
- Linux日志选项详解及日志服务器的实现
- python教程:闭包函数
- oracle 授权 传递,Oracle基础学习4--Oracle权限传递
- flink file sink
- 【Linux】一步一步学Linux——skill命令(143)
- oracle备份能备份索引吗,ORACLE会使索引失效的条件
- DEDECMS之二 如何修改模板页
- IDEA代码格式化会快捷键Ctrl+Alt+L失效
- 前端JS、Vue实现海康萤石直播预览、回放、云台控制功能
- 用HOOK机制让自绘菜单栏控件模拟系统菜单栏行为
- linux-centos 7 系统设置时区及同步时间
- Keil升级到AC6后,到底有哪些变化?
- error C2039: ‘tr1‘: is not a member of ‘std‘
- 不能打开淘宝单个商品页面
- 计算机的aero界面是一种,Win7家庭高级版特色功能 Aero桌面主题
- 拣货单Picket Ticket
- vlc插件详细使用说明
- MySQL 数据表优化设计(六):id 该如何选择数据类型?