Python 编程导论 Chapter 3 —— 一些简单的数值程序

文章目录

  • Python 编程导论 Chapter 3 ——一些简单的数值程序
      • 3.1 穷举法
      • 3.2 for 循环
      • 3.3 近似解和二分查找
      • 3.4 关于浮点数
      • 3.5 牛顿-拉弗森法

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}')

你可能感兴趣的:(MIT,Python,编程导论,Chapter,3,数值程序)