mirror of https://github.com/Mabbs/mabbs.github.io
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							99 lines
						
					
					
						
							2.6 KiB
						
					
					
				
			
		
		
	
	
							99 lines
						
					
					
						
							2.6 KiB
						
					
					
				--- | 
						|
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) | 
						|
``` | 
						|
  感觉好难受,每次在网上搜的代码都比我写的好……算了,反正我也是在学习嘛。    | 
						|
  后来我听说用欧拉筛法的效率更高……可惜我看完后不太理解……质数算法可真是复杂啊……
 | 
						|
 |