《从问题到程序:用Python学编程和计算》——3.5 练习

3.5 练习

概念和理解
1. 复习下面概念:数值积分,区间分割法,舍入误差,简单重复,累积,累积变量,生成和筛选,递推,递推变量,素数(质数),因子和真因子,哥德巴赫猜想,输入循环,输入控制的循环,递归定义,递归函数,循环定义,无穷递归,循环和递归,斐波那契数列,二路递归,计时,循环不变式,计算复杂性,最大公约数,欧几里得算法(辗转相除法),河内塔问题,自递归,相互递归,程序终止性,不可判定,Collatz猜想,唯一定义原则,自下而上,自顶向下,逐步求精,形式参数(形参),文档串,实际参数(实参),类型错误,全函数,参数检查,断言语句,通用和专用的方法,枚举和检查,二分法,绝对误差,相对误差。
2. 请分析3.1.2节中定义的函数mysin的执行,为什么它对越大的实参误差越大?请考虑用Python做一些试验,分析并总结试验中看到的情况。
3. 请证明如果一个自然数有真因子,一定有小于其平方的真因子。
4. 请分析3.2.2节改进的乘幂函数,设法弄清它对一般的自然数n计算power(x, n) 时要做多少次乘法和加法。
5. 请设法论证3.2.2节改进的乘幂函数对任何非负整数乘幂参数都能终止。
6. 请在你计算机上试验递归的fib函数,看看算到第几个斐波那契数时,计算的时间就超过了10秒钟,半分钟和一分钟。
7. 请设法论证3.2.4节最后用for结构描述的fib函数的正确性。
8. 请设法说明3.2.5节中常用辗转相除法定义的函数一定能求出最大公约数。
9. 请证明对河内塔问题,搬移n个圆盘时正好调用moveone函数2n - 1次。
10. 对一些n值试验河内塔程序,给它们计时。据此估计你所用计算机搬完64个金盘需要的时间。再去掉程序执行中的输出(例如把moveone的体改为一个return语句)后重新试验。如果僧侣们1秒钟搬金盘1次,搬完64个金盘需要多少时间?将这一时间与科学家对宇宙从大爆炸至今的估计寿命比较,据此评价僧侣们的说法。
编程练习
1. 无穷级数4/1 - 4/3 + 4/5 - 4/7 + ... 的和是圆周率,请写一个程序计算出这一公式前n项的值,同时给出所得结果与值的差。
2. 请写一个程序,计算连分式1 + 1 / (1 + 1 / (...(1 + 1 / (1 + x)))),是有n层嵌套的连分式。其中的n和x由输入得到。再把程序改为一个函数定义。
3. 请写程序计算调和级数的部分和,检查这个“和”在你机器上达到10、11、...、16、17、18时所用的时间,输出这些结果。你看到了什么情况?(请在你的程序文件里用注释的方式说明试验的情况。)
4. 假设1元钱买一瓶水,三个空瓶可以换一瓶水。初始n元最终可以喝到几瓶水?
5. 如果一个正整数m的所有因子(包括1,但不包括m自身)之和s等于m,则称m为完全数;当s < m时称m为亏数;当s > m时称m为盈数。请定义一个函数,在参数m为亏数、完全数或盈数时分别返回 -1、0、1。基于这个函数定义另一函数,它检查a到b范围里的整数,统计其中亏数、完全数和盈数的个数并输出。最后调用你定义的函数统计几个范围里的整数的情况。
6. 天才数学家Srinivasa Ramanujan发现了下面无穷级数:

请定义函数,基于这个级数计算圆周率。
  1. 请定义函数is_palindrome(s),它检查字符串s是否回文,也就是说,正向读和反向读一样的字符串。例如 "123454321" 就是一个回文数字字符串。
  2. 请定义函数make_palindrome(s),它从任意字符串s做出一个回文字符串,其中前面一段是原字符串。例如,make_palindrome("abcd")应得到 "abcdcba"。定义中只使用已经介绍过的几个字符串操作。
  3. 一个单词是字符串里的连续的几个字符。请定义函数has(s, w),它检查字符串s里是否出现单词w,如果出现就返回True,否则返回False。注意,这里你可能需要用到字符串长度、字符串切片的操作。只能使用已介绍的几个字符串操作。
  4. 写一个二进制浮点数转换计算器程序,通过输入送给它任意一个包含(一个)小数点的二进制串,它求出相应的浮点数并输出。该程序应反复读入二进制串并输出,直到人输入特殊的串end。
  5. 请修改3.1.3节求输入的10个正数之平均值的程序,保证在修改程序时,只要修改给变量num赋的值,函数的输出(包括输出的信息串)都正确了。
  6. 基于第2章有关三角恒等式检查的练习,写几个交互式的三角恒等式检查程序。执行时反复要求输入,完成检查并输出结果。
  7. 请考虑3.2.5节提出的另一种求最大公约数的方法:令一个变量从某个数开始取值,而后令其值递减,找到的第一个公约数就是两个参数的最大公约数。定义一个函数实现这种算法,并论证该函数能保证找到最大公约数。
  8. 函数f (n) 由如下规则定义:当n小于3时,f (n) = n;对于更大的n,f (n) = f (n-1) + 2 * f (n-2) + 3 * f (n-3)。请采用递归的方式直接定义一个计算f的函数,再按照递推的方式用循环结构定义一个计算f的函数。
  9. 请修改硬币兑换程序,改为先试验小币值硬币,后试大币值硬币。看看是否还能得到正确结果。另一方面,用一些总币值做试验,比较这种方法与正文中给出的方法,在求解时间上有没有差异。如果有差异请设法给出,说明为什么某种方法更好。
  10. 有人提出可以通过一个6重循环计算硬币兑换问题。请考虑这一可能性,设法定义一个函数。请比较你写出的函数和本章正文中给出的函数。
  11. 著名的Ackermann函数Ack(m, n) 定义如下:



    请将其定义为Python函数,并试验求几个值。例如Ack(3, 4) 应该得到125,请试试更大的参数,看看函数值随着参数而增长的情况。
  12. 请修改collatz函数,令其统计并输出:得到结果的过程中操作的步数,计算中连续下降超过三步的阶段数。
  13. 请利用(修改/使用)3.3.2节讨论的Collatz函数,定义三个函数:第一个函数返回(注意,不是输出)对正整数n做Collatz计算的过程中历经的最大值。第二个函数检查m到n的所有正整数,输出其中造成Collatz函数迭代次数最多的数k以及它的迭代次数;第三个函数检查从m到n的所有正整数,找出其中的k,在对k的迭代中历经的最大整数值比其他数都大,输出k和对它的迭代中达到的最大数值。
  14. 请基于3.4.2节的函数,定义几个画出规范图形的函数,例如矩形、菱形、六边形等。
  15. 为各种字符图形函数增加一对描述基准点的参数。
  16. 请定义函数draw_4square(m, n),它能输出用字符"-", "|", "+"拼出的“田”字,四个小方块的长度和宽度分别为m和n个字符或行数。例如,drawTian(4, 2)输出下面的“田”字。(注意,为了保证空格和各种字符宽度相同,以便输出字符对齐,应该把Python Shell的窗口设置为采用某种等宽字体输出。)
    +----+---+
    | | |
    | | |
    +----+---+
    | | |
    | | |
    +----+---+
  17. 基于你完成上面函数的认识定义另一个函数draw_board(m, n),它能生成用同样三个字符拼出的m * n个格子的棋盘(例如8*8个格子的国际象棋棋盘)。请注意在工作中定义有用的辅助函数。
  18. 请定义一个函数prime_factors(n),它设法找出正整数参数n的所有素因子,并调用print逐个输出,重复的因子重复输出。请在函数开始检查参数情况,只对满足函数要求的参数做计算。
  19. 请搜索互联网,设法找到另一种判定素数的方法,并将其实现为Python函数。
  20. 哥德巴赫猜想说任一大于等于6的偶数可以分解为两个奇素数之和。正文中给出了利用函数is_prime分解的函数定义。请尝试不定义辅助函数,直接定义一个在一定范围内检查哥德巴赫猜想的函数,执行中给出遇到的各偶数的素数分解。请从各方面比较这两个函数定义。另外,再请利用素数判断函数定义一个函数,它对6到n的偶数输出其素数分解,而且保证对每个偶数只输出一种分解。
  21. 利用前面给的代码,比较采用二分法求立方根和采用立方根逼近公式两种计算的操作效率。用给定范围中的一组等差值检查它们的迭代次数,并生成出比较结果的表格。
  22. 假设需要从很长的钢条上剪裁出长度为5cm、8cm、17cm和28cm的短条。请写一个函数,它计算出从长度为n cm的钢条上裁出这些短条的不同方式的数目,要求浪费的钢条长度不超过3cm。(注意:裁短钢条的不同方式与顺序无关。请考虑如下递归看法:从长度为n的钢条上剪裁的不同方式等于...)。在上面的程序里用注释形式论述你的做法的正确性。请在定义好函数之后,调用它求出对100cm、160cm和240cm的钢条的计算结果,以清晰明了的形式产生输出。
  23. 作业中有些题目要求定义函数。请在每个函数定义后面附加几行代码,调用所定义函数做几个典型计算,并用print以容易看明白的方式输出计算结果(产生的输出行中应说明输出的是什么)。
时间: 2024-11-02 12:45:50

《从问题到程序:用Python学编程和计算》——3.5 练习的相关文章

《从问题到程序:用Python学编程和计算》——第1章 程序设计和Python 1.1 计算机和程序

第1章 程序设计和Python 我们已经生活在信息时代,环顾四周,信息技术的影响无处不在.由于信息科学技术的发展和应用,我们的世界的方方面面都与20年前大不相同了,例如: 个人生活:看看人们在每天生活中做的各种事情,有多少是在与屏幕键盘(可能是触摸屏)交互,这些都是20年前没有的事情. 人际交流:20年前的人际交流方式很简单.除面对面交流外,只能通过纸笔写信或长途电话(要找专门的电话或者到电话局).今天人手一部手机,可以通过电话.短信.各种网络即时消息相互交流.电子邮件也是私人之间的交流媒介,而

《从问题到程序:用Python学编程和计算》——导读

前 言 计算机诞生至今不过六七十年,但它已经改变了世界,改变了每个人的生活.人们每天都在与计算机交流(如智能手机),各领域专业人员的大量日常工作都需要使用计算机,从事与计算机相关工作的人们已经发展为社会上最大的专业技术社团.计算机的研究和应用.互联网和其他相关领域,还在不断呼唤大量熟悉计算机的专业开发人才.计算机科学技术的开发和应用能力已被广泛认为是国家竞争力的重要组成部分.因此,学习计算机科学技术知识,不仅是社会发展的需要,而且已成为个人的重要职业竞争力.然而,要深入理解计算和计算机,使其成为

《从问题到程序:用Python学编程和计算》——1.2 Python语言简介

1.2 Python语言简介 本节将首先简单介绍Python语言的一些基本情况,包括其发展和使用的情况.而后介绍Python语言系统的安装和使用方面的基本常识.1.2.1 Python语言的发展和应用 Python语言是CWI(荷兰国家数学和计算机研究中心)的程序员Guido van Rossum在1989年开始开发的一种高级编程语言,当时的主要设计目标是希望能用于方便地管理CWI的Amoeba操作系统.后来,由于其各方面的优点而逐渐流行起来. Python语言现在由Python软件基金会(Py

《从问题到程序:用Python学编程和计算》——2.8 重复计算和循环

2.8 重复计算和循环 在前面几节,我们首先看到如何通过语句的顺序组合构造最简单的程序,这种程序是直线型程序,就是简单的一系列语句.这样的程序中只有一条执行路径(一种可能执行方式):Python解释器顺序执行程序里的语句,每个语句执行一次,当语句序列中最后一条语句的执行结束时,整个程序的执行就结束了. 增加了if复合语句,能写出的程序更多,程序的形式也更丰富,其中出现了选择和分支.这样得到的程序可称为分支程序.在分支程序里,每条基本语句最多执行一次,如果实际条件导致的执行没进入某个分支,该分支里

《从问题到程序:用Python学编程和计算》——3.4 定义函数

3.4 定义函数 在最简单的程序中,可能只用到表达式.语句和几种控制结构.但是,仅限于这些基本机制,很难写出很长的解决复杂问题的程序.随着遇到的问题更复杂,我们必须组织好程序的结构,在语句层面之上的基本结构就是函数.一个函数包装起一段代码并给予命名,引进参数将其通用化.定义好的函数可以通过调用表达式使用,非常方便.学习编程的重要一步就是学习定义函数:理解为什么需要定义函数,学会识别编程中定义函数的需求,掌握正确定义函数的技术.本小节和下一章将集中讨论这个问题.3.4.1 为什么定义函数 实际中需

《从问题到程序:用Python学编程和计算》——第3章 基本编程技术 3.1 循环程序设计

第3章 基本编程技术 第2章讨论了简单的计算和编程,展示了一些实例.通过对有关内容的学习,读者应该已经做了一些简单程序,对写程序和做计算有了些实际体会.虽然编程中细节较多,但也是很有趣的工作.为了完成一个程序,首先要分析问题.寻找解决方案,这些需要发挥人的聪明才智和想象力,也可能涉及一些相关领域的知识.要把设计变成可以运行的程序,既需要智力,也需要有条理的工作,一个小错误就可能使程序不能正确执行.当然,高度精确性也是现代社会对人的基本要求,写程序的过程能给我们许多有益的经验. 学习编程要经历一个

《从问题到程序:用Python学编程和计算》——1.3 程序开发

1.3 程序开发 在用Python学习编程时,自然需要了解Python语言,但更重要的是学习.理解和运用人们长期程序设计工作总结出的经验,包括正确的思考问题方法.正确的程序开发方法以及一些有益的常规做法,还要养成良好的编程习惯.随着学习的深入,需要解决的问题也会变得越来越复杂(当然,实际中的问题和解决它们的程序更复杂得多).比较复杂的东西不是随随便便就能做好的,需要认真工作,也需要正确的工作方法.本书中许多地方提出了这些方面的建议,希望引起读者的重视. 本节简单讨论程序的开发过程,包括程序的设计

《从问题到程序:用Python学编程和计算》——2.11 补充材料

2.11 补充材料 本书各章的主要内容将围绕着怎样通过编程解决计算问题展开,正文中对Python语言的机制只做必要的说明,有些细节情况没有涉及.另外,用Python编程也有许多有趣而且有用的技术.如果在各章的主要部分详细罗列,也可能冲淡讨论的主线.但是上述两方面的一些情况也值得介绍.本书采用的方法是在一些章的最后增加称为"补充材料"一节,补充一些细节,供读者参考,也供用本书教授课程的教师选用. 除了讨论语言细节和编程技术的两个小节外,有时还总结了一些常用的编程模式.练习中的第1题总是对

《从问题到程序:用Python学编程和计算》——2.5 标识符、变量和赋值

2.5 标识符.变量和赋值 前面用表达式做的计算都是各自独立的,实际上是把Python用作一个简单计算器.在提示符下输入一个合法的表达式,解释器处理该表达式,得到一个结果.不同表达式的计算相互无关.显然,这种方式很有局限性,只能完成最简单的计算工作.复杂的计算可能需要经过许多步骤,每步做一点计算工作并记录得到的结果,再基于已得到的结果一步步继续工作下去.要实现这种计算方式,就要有记录计算结果的方法. 2.5.1 变量.名字和值 Python中记录计算结果的机制称为变量.一个变量有一个名字,在程序

《从问题到程序:用Python学编程和计算》——2.6 简单脚本程序

2.6 简单脚本程序 一个Python程序(脚本)是一个独立的文件,文件的扩展名用py,文件的内容应该是一些Python命令(语句).把这种脚本送给Python解释器,令其执行,就能看到执行的效果.本节介绍脚本的建立和执行,以及程序在运行中与人交换信息的问题.[ 实际上,完全可以用任何文本编辑器,所有功能强大的Python程序开发环境也都提供了编辑Python程序的功能.可以根据自己的需要和考虑自行选择.但下面只考虑用IDLE编辑的问题.] 2.6.1 脚本的编辑和执行 一个Python脚本的内