《programming for the puzzled》第七章
涉及到的知识浮点数和算术运算,二分搜索。
问题:找到一组数的平方根。
迭代搜索
已知一个数n是完全平方数,可以从1开始计算其平方值,如果小于n,加一,再重复,直到其平方值等于n。这对于计算机来说是可行的,但还有更快的解法。
先实现这个算法吧。
1 | # coding:utf-8 |
现在进行改进,输入数据包括最小误差,步长,不把答案局限在整数解,求小数解。
1 | # 改进,增加答案精度,指定精度和步长 |
有时求解会失败,原因是循环跳过了答案。解决办法是减小每次迭代的递增值。但这会显著增加运行时间。
处理浮点数要注意,它们可能不像你想象的那样运行。
改进方法是用分治法,像上一章那样。
思路是,如果猜了一个数,其平方值比n小,那么所有大于该数的值都排除了,反过来可以排除所有小于该值的值。
1 | # 二分搜索 |
比第一种算法快得多,而且不会出现跳过答案,求解失败的情况。这里面隐含了一个性质,如果x>y>0, x^2>y^2>0。
另一个例子,二分查找。一个有序的数列,要找到一个数是否在这个数列里。
1 | # 线性查找 |
在一些问题里,三分查找更方便。
练习1,当n=0.25或者n<1-eps的情况,二分搜索会失败。找到原因并解决。
1 | # 二分搜索改进版 |
当n小于1时,答案可能不在计算的[low, high]区间里。
练习2.在bsearch里增加一个变量,记录搜索的区间长度。当列表长度小于一定值的时候,使用二分搜索还不如使用顺序搜索。
1 | # 二分查找 |
练习3.修改bisection程序找到方程x3+x2-11的解,误差给定(如0.01)。你也许需要从一个跨过0的区间开始,如[-10, 10]。
1 | # 练习3,求方程的根 |
我发文章的三个地方,欢迎大家在朋友圈等地方分享,欢迎点“在看”。
我的个人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的微信个人订阅号:赵瑜敏的口腔医学学习园地