例子1:判断一个数是不是素数。
首先要了解该题目的意思,什么是素数?除了1和自身能被整除之外,其他数字都不能被整除的数为素数。
方法一:
那么我们可以根据素数的定义来展开程序的构造,1和自身能被整除,假如此数为n,1~n这个范围中可以将1和n视作两个边界,其中的数都不被整除即可,这样的话我们可以使用range()函数和%取模运算来展开代码。
1 # coding=gbk
2 while True:
3 n = int(input("请输入一个整数:"))
4 if n < 2:
5 print(str(n),"不是素数也不是合数!")
6 else:
7 for i in range(2,n):
8 m = n % i
9 if m == 0:
10 print(str(n),"不是素数!")
11 break
12 else:
13 print(str(n),"是素数!")
1是一个边界,做特殊处理,4~5行代码。被除数从2开始算起,range()函数含左不含右,使用for循环挨个去小于n的正整数,n对其一次取模与0作比较,若等于0,进入if,输出不是素数且break终止循环,若不等于0,直接进入else,输出是素数。
在这里要注意一个问题,如下图所示:
程序里的第二个else不是和第二个if一起搭配的,如果写成图中所示,那么会出现错误,9、15等数会显示是素数,但是9、15这些数是会被3和5整除的。那么这个错误是怎么出现的呢?假如n=9,那么,进入for循环后,i取2,9%2不等于0,因此会进入else输出是素数,也就意味着i在range()函数里不会继续走下去,不会继续等于3~8,自然不会有9%3这种判别。因此,上图中的第二个else完全是没有意义的。必须让i遍历完所有的数,被n取模运算后,才能得出是不是素数的结论。
方法二:
第一种方法,逻辑思维很简单,但是如果是一个很大的数值,从2开始逐个寻找被除数,代码的运行速率会明显得降低,那么,我们可以将方法一中的代码进行优化处理。
黄色框之内的代码就是优化代码,(n**0.5)+1是对n开方+1,+1的意思是保证有些数开方后的余数可以进1,这里range()函数的取值范围就比第一种方法小得多,运行起来也效率高的多。(n**0.5)+1的前面要记得加上int(),因为这里是整数运算,开方后的数值类型为浮点数,要取其整数部分。
例子2:列出10万以内的所有素数。(这里考验的是程序的效率问题)
该例子可以使用例子1中的代码进行修改,如下图所示,这里用到了计时模块,可以看出该代码的运行时间为3.73秒
1 # coding=gbk 2 num = int(input('请输入你所需要的数值范围:')) 3 print('该数值范围内的所有素数为:') 4 import datetime 5 # import datetime这里用到了计时模块 6 start = datetime.datetime.now() 7 # 开始计时,赋值给start 8 for a in range(2,num): 9 for b in range(2,int(a**0.5)+1): 10 if a % b == 0: 11 break 12 else: 13 print(a,end=' ') 14 delta = (datetime.datetime.now() - start).total_seconds() 15 # 结束计时,赋值给delta 16 print() 17 print(delta) 18 19 # 第9行用到了开方的方法 20 21 ################################################## 22 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py 23 请输入你所需要的数值范围:100000
24 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 …… 26 0.720588 27 28 Process finished with exit code 0
1 # coding=gbk 2 num = int(input('请输入你所需要的数值范围:')) 3 print('该数值范围内的所有素数为:') 4 print(2,end=' ') 5 import datetime 6 # import datetime这里用到了计时模块 7 start = datetime.datetime.now() 8 # 开始计时,赋值给start 9 for a in range(3,num,2): 10 for b in range(3,int(a**0.5)+1): 11 if a % b == 0: 12 break 13 else: 14 print(a,end=' ') 15 delta = (datetime.datetime.now() - start).total_seconds() 16 # 结束计时,赋值给delta 17 print() 18 print(delta) 19 20 # 这里注意素数的性质,第9行代码里刨除了2这个特殊情况,以3开始,因为所有的偶数都不是素数,只看奇数即可。 21 # 记得不要忽略2这个特殊情况,第4行代码 22 ################################################ 23 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py 24 请输入你所需要的数值范围:100000 25 该数值范围内的所有素数为: 26 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 ……
27 0.62263 28 29 Process finished with exit code
# 在这里其实还能进一步的进行代码的优化,将b的for循环的代码(第10行代码)更改一下,for b in range(3,int(a**0.5)+1):变成for b in range(3,int(a**0.5)+1,2):步长为2,这样的话,该代码的效率还会提升。
1 # coding=gbk 2 num = int(input('请输入你所需要的数值范围:')) 3 print('该数值范围内的所有素数为:') 4 print(2,3,end=' ') 5 import datetime 6 # import datetime这里用到了计时模块 7 start = datetime.datetime.now() 8 # 开始计时,赋值给start 9 num = num - num%6 10 for a in range(5,num,6): 11 for b in range(2,int(a**0.5)+1): 12 if a % b == 0: 13 break 14 else: 15 print(a,end=' ') 16 num = a + 2 17 for b in range(2,int(a**0.5)+1): 18 if num % b == 0: 19 break 20 else: 21 print(num,end=' ') 22 delta = (datetime.datetime.now() - start).total_seconds() 23 # 结束计时,赋值给delta 24 print() 25 print(delta) 26 # 这里利用了素数的一个特性,大于等于5的素数一定和6的倍数相邻,代码第9、10行 27 # 要注意5前面的素数要额外输出,代码第4行 28 ############################################### 29 D:untitledproject2venvScriptspython.exe D:/untitled/project2/day1/refefe.py 30 请输入你所需要的数值范围:100000 31 该数值范围内的所有素数为: 32 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67……
33 0.614633 34 35 Process finished with exit code 0
显示10万以内的素数的方法还有很多,通过上述的几种方法来看,减少遍历的数字是提高代码效率的根本,第二种方法只检索奇数,一下就少了很多的遍历次数,第三,四种方法每隔6个数遍历一次,也省略了很多的遍历次数。