mirror of
https://github.com/Mabbs/mabbs.github.io
synced 2025-09-10 12:25:24 +02:00
Restore deleted repositories
This commit is contained in:
99
_posts/2019-10-21-python.md
Normal file
99
_posts/2019-10-21-python.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
layout: post
|
||||
title: Python学习笔记 - 求质数
|
||||
tags: [Python, 质数, 学习笔记]
|
||||
---
|
||||
|
||||
讲真,我酸了……<!--more-->
|
||||
|
||||
# 起因
|
||||
在学习Python的过程中,我和同学举行了一个比赛,大概内容是用Python做一个时间复杂度最低的质数生成器。
|
||||
在学校里就是有个好处,学校网络上知网下论文是免费的,我大概的查了一下,好像用埃氏筛法的效率比较高。
|
||||
以前我用Linux Shell也写过一个:
|
||||
```shell
|
||||
#!/system/bin/sh
|
||||
max=1000
|
||||
list="2"
|
||||
rlist="2"
|
||||
i=3
|
||||
while [ $i -lt $max ]
|
||||
do
|
||||
[ "$(
|
||||
echo "$list"|while read a
|
||||
do
|
||||
[ "$(($i%$a))" == "0" ]&&{
|
||||
echo "1"
|
||||
break 1
|
||||
}
|
||||
done
|
||||
)" == "1" ]||c=$i
|
||||
|
||||
[ "$bj" == "" -a "$c" != "" ]&&{
|
||||
[ "$((${c}*${c}))" -gt "$max" ]&&bj="1"
|
||||
}
|
||||
|
||||
[ "$c" == "" ]||{
|
||||
[ "$bj" == "1" ]||{
|
||||
list="$list
|
||||
$c"
|
||||
}
|
||||
echo "$c"
|
||||
}
|
||||
c=""
|
||||
i="$(($i+1))"
|
||||
done
|
||||
```
|
||||
不过效率极低……因为原生Shell是不支持数组之类的东西,所以其实并不能完全使用埃氏筛法……
|
||||
|
||||
# 使用Python做一个
|
||||
当然Python还是可以用的,于是我理解了一下,做了一个出来:
|
||||
```python
|
||||
maxprime=100000
|
||||
rprimeset=set(range(2,maxprime+1))
|
||||
lprimeset=set()
|
||||
lastprime=0
|
||||
while lastprime<=maxprime**0.5:
|
||||
lastprime=min(rprimeset)
|
||||
rprimeset=rprimeset-set(range(lastprime,maxprime+1,lastprime))
|
||||
lprimeset.add(lastprime)
|
||||
primelist=sorted(list(rprimeset|lprimeset))
|
||||
print(primelist)
|
||||
#print(primelist,file=open(__file__[:__file__.rfind("/")]+"/prime.txt",'w+'))
|
||||
```
|
||||
这个效率确实比Shell做的好太多了,而且看起来也清晰易懂。在我的电脑上,1000000的质数只需要4s就能算出来
|
||||
|
||||
# 结局
|
||||
不过我后来在某百科上查了一下他们用埃氏筛做的Python版本……然后我就酸了……他们的代码在我的电脑上只需要0.6s就能跑完1000000的质数……而且我估计他们的空间复杂度还比我小……
|
||||
```python
|
||||
# python 原生实现
|
||||
|
||||
def primes(n):
|
||||
P = []
|
||||
f = []
|
||||
for i in range(n+1):
|
||||
if i > 2 and i%2 == 0:
|
||||
f.append(1)
|
||||
else:
|
||||
f.append(0)
|
||||
i = 3
|
||||
while i*i <= n:
|
||||
if f[i] == 0:
|
||||
j = i*i
|
||||
while j <= n:
|
||||
f[j] = 1
|
||||
j += i+i
|
||||
i += 2
|
||||
|
||||
P.append(2)
|
||||
for x in range(3,n+1,2):
|
||||
if f[x] == 0:
|
||||
P.append(x)
|
||||
|
||||
return P
|
||||
|
||||
n = 1000000
|
||||
P = primes(n)
|
||||
print(P)
|
||||
```
|
||||
感觉好难受,每次在网上搜的代码都比我写的好……算了,反正我也是在学习嘛。
|
||||
后来我听说用欧拉筛法的效率更高……可惜我看完后不太理解……质数算法可真是复杂啊……
|
Reference in New Issue
Block a user