Python数学编程第1讲 2020.10.24
回顾上节练习
据说数学王子高斯小时候,数学老师曾让他们计算1+2+3+4+5+6+……+100的得数,同学们都忙着挨个挨个地相加,只有高斯巧妙发现了快速计算的方法,很快就得出了结果。你能不能教计算机用这两种方法各算一下?
挨个挨个地相加的方法,我们可以用range函数生成数列,在for in循环中累加这些数。
n=100
sum1=0
for i in range(1,n+1):
sum1=sum1+i
print(sum1)
大家也可以把最后一行的print函数缩进4格,对齐上一行,看看运行效果。
小高斯想到的方法,大家知道吗?
n = 100
print((1+n)*n//2)
算了累加,再试试算累程,编程序算一下1x2x3x4x5x6x7x8x9x10=?
把上面累加的程序稍加改动,是不是就能算出来?
n=10
sum1=1 # 注意乘积的初值要设为1
for i in range(1,n+1):
sum1=sum1*i # 累乘
print(sum1)
判断质数程序的改进
n = 100 # 设n为100
sum = 0 # 计数器sum清零
for i in range(1, n+1): # i依次从1……n取出一个数
if(n%i==0): # 如果i能整除n,计数器累加1
sum = sum + 1
if(sum==2): # 如果因数只有两个n就是质数,否则n是合数
print('%d是质数' % n)
else:
print('%d是合数' % n)
上次我们写的判断质数的程序。如果n很大,就要算好多次,程序运行时间很长。有没有更好的方法呢?
我们是按质数的定义去把n所有的因数都数出来。其实反过来想想,除去1和n,如果还存在另外的因数,是不是就表明n不是质数,而是合数,结束判断了?
把原来的程序稍加改动,很快得到以下代码:
n = 100
for i in range(2, n): # i依次从2……n-1取出一个数
if(n%i==0): # 如果i能整除n,说明n是合数
print('%d是合数' % n)
break # break语句跳出for in循环
print('%d是质数' % n)
这个程序在n是质数的时候结果正确,当n是合数的时候有毛病,因为最后一个print函数总是会执行。通常的一种解决方法是定义一个变量来记录状态,再根据标志变量的状态执行相应内容。
n = 100
flag = 1 # 定义标志变量,设初值
for i in range(2, n):
if(n%i==0):
print('%d是合数' % n)
flag = 0 # 改变标志变量的值
break
if(flag==1): # 判断标志变量的状态
print('%d是质数' % n)
如果n的因数较早出现的话,我们这个程序很快就能完成判断,否则还是很慢。再想想改进的办法吧!
分解一个数的因数,因数通常都是成对出现的。
100 = 1 x 100
100 = 2 x 50
100 = 4 x 25
100 = 5 x 20
100 = 10 x 10
100 = 20 x 5
100 = 25 x 4
100 = 50 x 2
100 = 100 x 1
我们只需要遍历到这个数的平方根,循环的次数就大大减少了。
n = 100
flag = 1
for i in range(2, int(n**0.5)+1): # int函数把数据转为整数
if(n%i==0):
print('%d是合数' % n)
flag = 0
break
if(flag==1):
print('%d是质数' % n)
好,判断质数程序的优化暂时就进行到这里。
验证哥德巴赫猜想
哥德巴赫猜想,最早是他在1742年给欧拉的信中提出的,现在常描述为任一大于2的偶数都可写成两个质数之和,简称1+1。
没想到这样一个简洁的猜想,近300年来,无人能证明,也没人能反驳,号称数学王冠上的钻石,是世界近代三大数学难题之一。
我们证明不了哥德巴赫猜想,但我们可以做验证啊,对指定的偶数,我们把它表示为两个质数的和。4=2+2,6=3+3,8=5+3,10=5+5……
怎么简单地编程呢?
我们还是可以挨个从2到N的一半,列出i和n-i,检查i和n-i是不是质数,如果都是质数,那我们不就找到所谓的1+1么 : )
n = 100
for a in range(2,n//2+1): # a遍历2到n的一半,判断a是不是质数
flag=1
for i in range(2, int(a**0.5)+1):
if(a%i==0):
flag=0
break
if(flag==1): # 如果a是质数,再判断n-a是不是质数
b = n - a
flag=1
for i in range(2, int(b**0.5)+1):
if(b%i==0):
flag=0
break
if(flag==1): # 如果n-a也是质数,输出结果
print(n,'=',a,'+',b)
看,我们做到了!
在这个程序里,判断质数的代码,我们贴了两遍,显得很啰嗦,有什么好的办法吗?
且听下回分解。