今天也是写代码
求出 10万以内的所有素数 并不断对代码性能进行优化
第一次写的 几天前的作业
这个代码bug 当 范围大于 100 时 求出的素数 有错误
11 x 11 =121 121 符合判断条件,但却不是素数
当时为了应急 没有仔细检查
#求10万以内的所有素数 除了1 和 自身,不能被其他数整除的数
for i in range(2,1000):
for j in range(2,10):
if i==j:
print(i)
break
if i%j==0:
break
if j==9:
print(i)
尝试对代码逻辑进行优化
暴力枚举 枚举10万以内的数 拥有大量重复,无效的运算
count=0
for i in range(2,100000):
for j in range(2,i+1):
if i==j:
count+=1
break
elif i%j==0:
break
if j==9:
count+=1
print(count)
#9592 这个结果计算了5分钟
尝试对算法进行优化
二分思想,分一半 应该也可以
from math import *
count =0
for i in range(2,100000):
y=int(i//2)+1 #简单除于 2
for j in range(2,y):
if i%j==0:
break
else: #如果 for 循环完了 ,就执行else 下的语句,反之被break打断 就不执行else里面语句
count+=1
print(count) # 打印了 3分钟 哭了
开根号优化
对一个数进行开根号 这个我没法解释(你知道的,我数学都还给数学老师了)
x * x = y 那么 x 就是 y 的根 x * x +1 必定大于 y
在这里应用到判断质数中 就可以省略很多运算
比如 100000 开根号 向上取整 才为 317
from math import *
count =0
for i in range(2,100000):
y=int(sqrt(i))+1 #开个根号 然后取上面的 那个数 乘法的终点就是开方值
for j in range(2,y):
if i%j==0:
break
else:
count+=1
print(count) #这个算法 5 秒
再次使用2分思维
偶数必定不是质数 除了 2
from math import *
count =1
for i in range(3,100000,2):
y=int(sqrt(i))+1 #开个根号 然后取上面的 那个数 乘法的终点就是开方值
for j in range(3,y,2):
if i%j==0:
break
else:
count+=1
print(count) #对半分 偶数有一半,直接去掉 直接优化到 2秒 (我怀疑是缓存)
最后使用 埃拉托斯特尼筛法
从2 开始将每个素数的各个倍数,标记为合数 然后 巴拉巴拉
看不懂
class Calculator(object):
def prime(self, n):
if n <= 2:
return 0
is_right = [True] * n
is_right[1] = False
for i in range(2, int(n ** 0.5) + 1):
if is_right[i]:
for j in range(i * i, n, i):
is_right[j] = False
m = 0
for x in range(2, n):
if is_right[x]:
m += 1
return m
x=Calculator()
x.prime(100000) #不到 1 秒 计算100万 也不到1秒
总结
- 从开根号开始 以后都是我从 百度等 各个渠道寻找的 代码
- 数学底子太差了 最近在补线性代数 哭了
- 果然程序写的好,数学少不了