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