|
|
- ---
- 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)
- ```
- 感觉好难受,每次在网上搜的代码都比我写的好……算了,反正我也是在学习嘛。
- 后来我听说用欧拉筛法的效率更高……可惜我看完后不太理解……质数算法可真是复杂啊……
|