在之前的学习中,我们学习了关于求幂的一系列算法;
比如求幂的递归算法,这个算法的体验和之前学习的阶乘的算法是差不多的;

一、求幂的递归算法实现
利用(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相关推荐

  1. 实现手机来电铃声,通知铃声、警告铃声等音频定制化功能(三,多媒体扫描结果定制处理)

    本篇博文主要是对MediaScanner中endFile方法的处理流程上的重构,以实现需求中的资源区域化定制.处理思路为首先扫描定制分区中的资源,在扫描系统分区下默认资源时判断定制分区西下是否已经存在 ...

  2. sqlserver错误码

    错误 6,000 到 6,999 错误 严重性 是否记录事件 说明 6001 10 否 SHUTDOWN 正在等待 %d 个进程完成. 6004 10 否 用户没有执行此操作的权限. 6005 10 ...

  3. [books] - SICP 2nd edition

    全名是: Structure and Interpretation of Computer Programs 中文名稱: 计算机程序的构造和解释 20131024 淘寶訂單 20131104 到手, ...

  4. 学习伯克利CS 61A课程(Structure and Interpretation of Computer Programs, SICP)的相关资源

    有个叫做Teach Yourself Computer Science的网站[1]教如何自学计算机科学,关于Programming这个方向推荐了<Structure and Interpreta ...

  5. SICP(计算机程序构造与解释)学习笔记(lisp语言实现)

    用的是这版本 由于逆天的语法,必须准确记清楚 目录 Scheme语法 递归与阶乘 1.递归与阶乘的区别 2.阶乘与递归的实例 阶乘的递归实现 阶乘的迭代实现 斐波那契数列的递归实现 1.3高阶过程实现 ...

  6. 计算机程序结构和解释,SICP 计算机程序的构造和解释

    <SICP 计算机程序的构造和解释>由会员分享,可在线阅读,更多相关<SICP 计算机程序的构造和解释(5页珍藏版)>请在人人文库网上搜索. 1.SICP 计算机程序的构造和解 ...

  7. 《SICP》习题第3章(施工中)

    本人做的SICP习题第3章,如有错误请指正,用的解释器是Racket 练习3.1 ;; 累加器 (define (make-accumulator initial)(lambda (x)(let (( ...

  8. UCB CS61A | SICP C1

    Textbook (SICP for python) It's adapted from the legendary book ----<Structure and Interpretation ...

  9. Go 1.16 的这个新变化需要适应下:go get 和 go install 的变化

    原文地址: Go 1.16 的这个新变化需要适应下:go get 和 go install 的变化 一直以来,go get 用于下载并安装 Go 包.命令等,而 go install 在 module ...

  10. 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 ...

最新文章

  1. 上班第一天公司要你用Spring Boot 实现万能文件在线预览
  2. CVPR 2020 Oral | 旷视提出Circle Loss,革新深度特征学习范式
  3. Linux日志选项详解及日志服务器的实现
  4. python教程:闭包函数
  5. oracle 授权 传递,Oracle基础学习4--Oracle权限传递
  6. flink file sink
  7. 【Linux】一步一步学Linux——skill命令(143)
  8. oracle备份能备份索引吗,ORACLE会使索引失效的条件
  9. DEDECMS之二 如何修改模板页
  10. IDEA代码格式化会快捷键Ctrl+Alt+L失效
  11. 前端JS、Vue实现海康萤石直播预览、回放、云台控制功能
  12. 用HOOK机制让自绘菜单栏控件模拟系统菜单栏行为
  13. linux-centos 7 系统设置时区及同步时间
  14. Keil升级到AC6后,到底有哪些变化?
  15. error C2039: ‘tr1‘: is not a member of ‘std‘
  16. 不能打开淘宝单个商品页面
  17. 计算机的aero界面是一种,Win7家庭高级版特色功能 Aero桌面主题
  18. 拣货单Picket Ticket
  19. vlc插件详细使用说明
  20. MySQL 数据表优化设计(六):id 该如何选择数据类型?

热门文章

  1. 故事系列之二:佛法世界中看天赋与勤奋
  2. html下划线怎么做成超链接,html超链接下划线应该加吗?
  3. tcp/ip协议的三次握手4次断开
  4. 原生JS实现FlappyBird游戏 超详细解析 快来做一个自己玩吧
  5. VS code(Visual Studio Code)乱码解决方法
  6. 股权投资模型-CAPM模型和PEG模型(内附示例数据)
  7. java8 stream 原理_【修炼内功】[Java8] Stream是怎么工作的
  8. 网页占满整个屏幕_css设置网页占满屏幕
  9. 打好高远球要注意的三要素
  10. 《西部世界》在线观看与观后感