Python 编程导论 Chapter 3 ——一些简单的数值程序
3.1 穷举法
#寻找完全立方数的立方根
x = int(input('Enter an integer: '))
ans = 0
while ans**3 < abs(x):
ans = ans + 1
if ans**3 != abs(x):
print(x, 'is not a perfect cube')
else:
if x < 0:
ans = -ans
print('Cube root of', x,'is', ans)
-
循环应该适用一个合适的递减函数
-
将程序映射为一个整数
-
进入循环它是非负的
-
当它小于等于0时,循环结束
-
每次循环它的值都会减小
-
穷举法,是猜测与检验算法的一个变种
3.2 for 循环
- Python 提供一种语言机制简化适用这种迭代方式的程序,for 循环
for variable in sequence:
code block
# for 后面的变量被绑定到序列中的第一个值
# 直到穷尽这个序列,或者执行到代码块中的break语句
# 绑定到变量的序列值通常使用内置函数 range 生成,它会返回一系列整数
# range 函数接受3个整数参数: start 、 stop 和 step
x = 4
for j in range(x):
for i in range(x):
print(i)
x = 2
# 假设 s 是包含多个小数的字符串,由逗号隔开,如 s = '1.23, 2.4, 3.123' 。编
# 写一个程序,输出 s 中所有数值的和
def sum_items(s) :
num_list = s.split(",")
num_float_list = []
result = 0
for item in num_list:
num_float_list.append(float(item))
for it in num_float_list:
result += it
return result
s = '1.23, 2.4, 3.123'
print(sum_items(s))
3.3 近似解和二分查找
-
求任意非负数的平方根(意味着找到一个近似解的平方根程序)
-
近似解位于实际解附近的一个常数范围内,这个常数我们称为 epsilon(误差区间)
# 求25数字的平方根(近似解)
x = 25
epsilon = 0.01 #设置误差区间,常数范围
step = epsilon**2 #设置猜测的最小移动单位,以0.0001的量进行递增猜测
numGuesses = 0 #总共经历的猜测数
ans = 0.0
while abs(ans**2 - x) >= epsilon and ans <= x: # 与我们实际目的反着来,当ans的平方减去原始值比误差范围大时 且 ans 小于等于原始值时,则本循环继续执行
ans += step #按照step递增
numGuesses += 1 #猜测数递增
print('numGuesses =', numGuesses)
if abs(ans**2 - x) >= epsilon:
print('Failed on square root of', x)
else:
print(ans, 'is close to square root of', x)
# 二分查找求x的平方根,利用数值的全序性
# 设定一个区间,从区间的中间开始查找,如果这不是正确答案(多数时候不是),那么就看看它是
# 太大还是太小。如果太大,我们就可以知道答案肯定位于左侧;如果太小,我们就知道答案肯定位
# 于右侧
x = 25 # 求解值
epsilon = 0.01 # 最大误差
numGuesses = 0
low = 0.0 # 最低起始值
high = max(1.0, x) # 最高值
ans = (high + low)/2.0 # ans的起始求解值
while abs(ans**2 - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x: # 如果 ans 的平方小于25
low = ans # 那么重新设定最低起始值为ans
else:
high = ans # 如果 ans 的平方大于25 则设置最高值为ans
ans = (high + low)/2.0 # 重新计算新的ans 进入循环
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
# 结果显示
low = 0.0 high = 25 ans = 12.5
low = 0.0 high = 12.5 ans = 6.25
low = 0.0 high = 6.25 ans = 3.125
low = 3.125 high = 6.25 ans = 4.6875
low = 4.6875 high = 6.25 ans = 5.46875
low = 4.6875 high = 5.46875 ans = 5.078125
low = 4.6875 high = 5.078125 ans = 4.8828125
low = 4.8828125 high = 5.078125 ans = 4.98046875
low = 4.98046875 high = 5.078125 ans = 5.029296875
low = 4.98046875 high = 5.029296875 ans = 5.0048828125
low = 4.98046875 high = 5.0048828125 ans = 4.99267578125
low = 4.99267578125 high = 5.0048828125 ans = 4.998779296875
low = 4.998779296875 high = 5.0048828125 ans = 5.0018310546875
numGuesses = 13
5.00030517578125 is close to square root of 25
# 这种算法每一步都将查找空间分为两部分,所以称为二分查找
3.4 关于浮点数
-
长度为n的序列可以表示10 n 个不同的数
-
二进制数10011,转化为十进制数为,1 * 24 + 1 * 21 + 1 * 20 = 19
-
对浮点数进行舍入操作,可以使用round函数。表达式:
round(x,numDigits)
# 返回一个浮点数,保留x后numDigits 的舍入值如:
print(ound(2**0.5,3))
# 结果是1.414
- 大多时候实数与浮点数之间的区别不重要,但使用==比较两个浮点数时候会产生不可思议的结果
- 更合适的做法是用比较法:
- abs(x-y) < 0.0001,就比x == y 更好
3.5 牛顿-拉弗森法
- 最常用的近似算法通常被认为出自艾萨克·牛顿之手,称为“牛顿法”,但有时也称为“牛
顿 - 拉弗森法”
#利用牛顿拉弗森法寻找平方根
#寻找x,满足x**2-24在epsilon和0之间
epsilon = 0.01
k = 24.0
guess = k/2.0
guess_num = 0
while abs(guess*guess - k) >= epsilon:
guess = guess - (((guess**2) - k)/(2*guess))
guess_num += 1
print('Square root of', k, 'is about', guess)
print(f'The guess number is {guess_num}')