按 ‘ 算法 ’ 标签归档

程序员入伙书——初涉算法

在以后的讲解里,会陆陆续续地涉及到许多算法。所以这里先给大家心里垫个底儿。如果你没有看明白这一节,不用很担心。

在“程序在干什么?”一节的最后,我举了一个例子,来说明程序具有计算、流程控制、输入输出三个功能块。这个例子是“求”一个数字的平方根,但它不是在“算”,而是在“猜”。

如果我给它的数是3,它就先猜:1.5!然后自己验算一把:1.5 x 1.5 = 2.25,太小。于是它就再猜:2.25!(就是位于1.5和3正中间那个数)验算一下:2.25 写2.25 = 5.0625,太大。再猜:1.875!——1.5太小,2.25太大,那一定在它们之间了。1.875是1.5和2.25的平均值。1.875 x 1.875 = 3.515625,又大了些,不过大家可以注意到,数字开始接近3了。于是它再取1.875和1.5的平均值……如此反反复复地接着猜下去,可以预知,猜测的结果必然会越来越逼近3的平方根。

我们都知道,第一、计算机无法精确表达实数。第二、即使从完美的数学上说,3的平方根是一个无理数,也不可能通过有限次的有理数四则运算实现。所以我就对程序说,你也不用太自责,只要误差小于亿分之一,你就可以从循环里退出来了。这样就不会出现这种情况:由于结果的平方总是不能精确等于3,程序过于内疚而陷入无限循环的困境。

现在咱们往那个程序里加两条调试语句:

print('Please input a number: ', end = '')
n = abs(float(input()))
high = max(1, n)
low = 0
while True:
    result = (high + low) / 2
    print('What about %.10g?' % result)
    print("%.10g x %.10g = %.10g" % (result, result, result * result))
    if abs(result * result - n) < n * 1E-8:
        break
    if result * result > n:
        high = result
    else:
        low = result
print('Square root of %g is %g' % (n, result))

再来跑一下,看看每次循环的中间结果。
猛击阅读全文