求100内的素数:再次优化版

'''
求100内的素数:再次优化版
'''

可以优化的地方:
1、素数是除了2 之外的奇数
2、并不是所有的奇数都是素数
3、素数只能被素数除尽
4、合数都能分解成素数的乘积
5、是否利用上一次产生的结果,作为本次循环的条件
6、是否有不需要的数也被除了一次,例如:质素集合大于 x ** 0.5的 不需要再循环了
'''

 1 # NO 1 最原始的算法
 2 n = 100
 3 count = 0
 4 
 5 for i in range(2,n):
 6     for j in range(2,i):
 7         if i % j == 0:
 8             break
 9     else:
10         count += 1 
11 print(count)
 1 # NO 2 
 2 # 2移除来
 3 # 素数是100以内的奇数
 4 # 除数从3 开始,因为2提出来,所以奇数是除不尽2。
 5 # 奇数只能被奇数除尽
 6 
 7 n = 100
 8 count = 1
 9 #primenumber = []
10 
11 for i in range(3,n,2): 
12     for j in range(3,int(i ** 0.5) + 1,2):
13         if i % j == 0:
14             break
15     else:
16         count += 1 
17         #primenumber.append(i)
18 print(count)
 1 # NO 3
 2 # 在2 之后的的偶数都输合数
 3 # 除了2 的合数都能分解因式为素数的乘积
 4 # 用上次的结果  这是编程里重要思想之一
 5 n = 100
 6 count = 0
 7 primenumber = []
 8 
 9 for i in range(2, n):
10     for j in primenumber: #利用上次的结果
11         # 奇数里也有合数,所以上面的范围range(3,int(i ** 0.5) + 1,2):可以改为质数
12         if i % j == 0:
13             break
14     else:
15         count += 1 
16         primenumber.append(i)
17 print(count)
 1 # NO 4
 2 # 上面的质数集合没必要全除,只需到 int(i**0.5) +1
 3 n = 100
 4 count = 1
 5 primenumber = [2]
 6 
 7 for i in range(3,n,2):
 8     flag = False # 假设进来的数不是合数
 9     for j in primenumber: #利用上次的结果
10         # 奇数里也有合数,所以上面的范围range(3,int(i ** 0.5) + 1,2):可以改为质数
11         if i % j == 0: # 找到合数
12             flag = True
13             break
14         if j > i ** 0.5: # 找到素数,当质数大于 i**0.5 之后就不用再除了
15                         # 但是每次进来 i ** 0.5 都要计算一次,又增加负担
16             break   
17     if not flag:
18         count += 1 
19         primenumber.append(i)
20 print(count)
 1 # NO 5
 2 # NO4 的修改版
 3 n = 100
 4 count = 1
 5 primenumber = [2]
 6 
 7 for i in range(3,n,2):
 8     flag = False # 假设进来的数不是合数
 9     edg = i ** 0.5
10     for j in primenumber: #利用上次的结果
11         # 奇数里也有合数,所以上面的范围range(3,int(i ** 0.5) + 1,2):可以改为质数
12         if i % j == 0: # 找到合数
13             flag = True
14             break
15         if j > edg: # 找到素数,当质数大于 i**0.5 之后就不用再除了
16             break   
17     if not flag:
18         count += 1 
19         primenumber.append(i)
20 print(count)
 1 # NO 6
 2 # 大于3 的素数只有 6N-1 或 6N+1
 3 # 5,7 ,11,13,17------补进数 2,4 交替出现
 4 # 优化点:可以将循环序列改为列表,利用之前的结果
 5 
 6 count = 2
 7 # primenumber = [2, 3]
 8 n = 100
 9 x = 5
10 setp = 2
11 while x <100 :   
12     for i in range(3, int(x ** 0.5) + 1, 2): # 这里的range() 是一次性算好的
13         if x % i == 0:
14             break        
15     else:
16         count += 1
17     x += setp
18     setp = 4 if  setp == 2  else 2   
19     print(count,setp)

 1 # NO 6 优化版
 2 count = 2
 3 primenumber = [2, 3] # #比较特殊所以取出来
 4 n = 100 
 5 x = 5
 6 setp = 2
 7 while x <100 :  
 8     edg = x ** 0.5
 9     flag = False
10     for i in primenumber: # 这里的range() 是一次性算好的
11         if x % i == 0:
12             flag = True
13             break
14         if i > edg:
15             break
16     if not flag:
17         count += 1
18         primenumber.append(x)
19     x += setp
20     setp = 4 if  setp == 2  else 2
21     
22 print(count)

 

 

posted @ 2018-08-09 11:02  JerryZao  阅读(327)  评论(0编辑  收藏  举报