我们学习了Python的循环语句和if分支结构后,就可以做很多是事情了:比如经典的求素数问题。
定义:一个大于1的自然数,只能被1和它自身整除的数。
根据定义要想判定一个大于1的数是不是素数,要整除从2开始到它自身截止在内的所有数根据能不能被整除来判断。
比如求100以内的素数只根据定义我们可以写成:
count = 0 #计数
for i in range(2,100):
for j in range(2,i):
if i % j == 0:
break
else:
count += 1
print(count)
但是这样的效率高效吗?我们求一下10000以内的素数看一下能用多久时间。首先调用一下求时间的函数:import datetime。
count = 0 #计数
time = 0 # 计时间
start = datetime.datetime.now()
for i in range(2,10000):
for j in range(2,i):
if i % j == 0:
break
else:
count += 1
time = (datetime.datetime.now() - start).total_seconds()
print(count)
print(time)
1229
0.749043
我们可以看到相对于计算机而言时间还是很长的。那么怎么在结构不变的情况下优化呢?其实完全可以从定义再入手,一个偶数肯定不是素数因此判定一个范围内的素数我们完全可以先把偶数去除。
print(2)
for i in range(3,10000,2):
这样很明白循环次数减少了近一半,节省了很多时间。但是只优化这点肯定是不够的,我们知道除了素数外,其它的数必定是两个数的乘积,并且这两个数一个大于等于该数的开平方,另一个小于等于该数的平方根。只要找到其中的一个另一个就不用除了,因此我们除到这个数的开平方根就行了。所以可以写成如下:
print(2)
for i in range(3,10000,2):
for j in range(3,int(i**0.5)+1):
然后还有一个优化点:既然我们已经知道了是在奇数群里找素数,那么也就可以不用除以偶数了,毕竟奇数除以偶数怎么也除不尽。当我们把这些优化点都加上去看一下所需的时间。
count = 1 #计数,把数字2也算上
time = 0 # 计时间
start = datetime.datetime.now()
for i in range(3,10000,2): #利用步长剔除偶数
for j in range(3,int(i**0.5)+1,2): #只除到平方根即可
if i % j == 0:
break
else:
count += 1
time = (datetime.datetime.now() - start).total_seconds()
print(count)
print(time)
1229
0.012
我们可以看到时间缩减了很多,效率大大提升!