mirror of
				https://github.com/Mabbs/mabbs.github.io
				synced 2025-11-03 20:18:21 +08: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