课程内容与目标:
- 加强写简单程序的能力
- 迭代或如何多次重复方法,以便重复利用计算多次执行
- 写出简单算法解决数值问题
1.一个简单的计算平方的小程序
x = 3
ans = 0
itersLeft = x
while(itersLeft != 0):
ans = ans + x
itersLeft = itersLeft - 1
print(str(x)+'*'+str(x)+'='+str(ans))
迭代的一些特征:
①我们需要在循环外设置一个迭代变量,即上例中的x和itersLeft
②需要一个测试变量itersLeft来决定什么时候结束
③需要改变循环中的变量
2.for循环:
基本形式:
for <identifier> in <sequence>:
<code block>
3.生成整数序列的方法:
内置函数range:
——range(n) = [0 ,1, 2, 3, ..., n-1]
——range(m, n) = [m, m+1, ..., n-1]
4.求整数的立方根
①简单方法:
x = int(raw_input('Enter an integer'))
ans = 0
while ans**3 < abs(x):
ans = ans + 1
if ans**3 != abs(x):
print(str(x) + 'is not a perfect cube')
else:
if x<0:
ans = -ans
print('Cube root of' + str(x) + 'is' + str(ans))
②优化方法:
x = int(raw_input('Enter an integer:'))
for ans in range(0, abs(x)+1):
if ans**3 == abs(x):
break
if ans**3 != abs(x):
print(str(x)+'is not a perfect cube')
else:
if x<0:
ans = -ans
print('Cube root of' + str(x) + 'is' + str(ans))
5.用for循环依次输出10,8,6,4,2
①方法一:
for num in range(0, 10, 2):
print 10 - num
②方法二:
for num in range(10, 0, -2):
print num
6.整数十进制转二进制
if num<0:
isNeg = True
num = abs(num)
else:
isNeg = False
result = ''
if num == 0:
result = '0'
while num>0:
result = str(num%2)+result
num = num/2
if isNeg:
result = '-'+result
7.浮点数十进制转二进制
x = float(raw_input('Enter a decimal number between 0 and 1:')) #以3/8=0.375为例,将0.375转为二进制
p = 0
while((2**p)*x)%1 != 0: #用于寻找2的幂次,将它转换成整数。此处找到p=3,使得(2**3)*0.375=3
print('Remainder=' + str((2**p)*x-int((2**p)*x)))
p += 1
num = int(x*(2**p))
result = ''
if num == 0:
result = '0'
while num>0:
result = str(num%2) + result
num = num/2
for i in range(p - len(result)): #result='011',长为3,需要左移3位,再循环一次加一个'0'即可添加小数点
result = '0' + result
result = result[0:-p]+'.'+result[-p:] #p为幂次,左移p位
print('The binary representation of the decimal '+str(x)+' is '+str(result))
8.求浮点数的平方根(近似的)
(1)穷举法:
x = 25
epsilon = 0.01 #计算值和真实值之间误差
step = epsilon**2 #增加的速度
numGuesses = 0 #猜测次数
ans = 0.0 #初始答案
#首先检验数值是否偏移过大
while (abs(ans**2 - x)) >= epsilon and ans <= x:
ans += step
numGuesses += 1
print('numGuesses = '+str(numGuesses))
if abs(ans**2 - x) >= epsilon:
print('Failed on square root of'+str(x))
else:
print(str(ans) + 'is close to the square root of' + 'str(x)')
①选择多大的步长合适呢?
如果设置的非常小,那么得到答案会发费很长的时间
如果设置的非常大,那么得到的答案不够精确,甚至找不到想要的答案
②总体来说,无论步长多大,它将花费大于x的次数来找到答案
③故需要更好地算法来解决这个问题
(2)二分查找法:
x = 25
epsilon = 0.01
numGuesses = 0
low = 0.0
high = x
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon:
print('low = '+str(low)+'high = '+str(high) + 'ans = '+ str(ans))
numGuesses += 1
if ans**2 < x: #此处不够严谨,详见第四讲
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =' + str(numGuesses))
print(str(ans) + 'is close to square root of'+str(x))
①二分查找法从根本上减少了计算的次数。而这也是原始数据中的一部分,即它不仅能快速运算,它还十分智能,知道我们想要如何解决问题
②二分查找法非常适用于拥有排序属性的问题
(3)牛顿拉夫逊算法
基本原理:g-p(g)/p'(g),其中g为估计值
一个简单的例子:
如x**2-k,那么其导数为2x,上式可化简为:
g-(g**2-k)/2g,其中k为真实值
这就是一个更加接近的答案
epsilon = 0.01
y = 24.0
guess = y/2.0
while abs(guess*guess - y) >= epsilon:
guess = guess - (((guess**2) - y)/(2*guess))
print(guess)
print('Square root of'+str(y) + 'is about'+'str(guess)')