summary refs log tree commit diff
path: root/_posts/2019-10-21-python.md
diff options
context:
space:
mode:
Diffstat (limited to '_posts/2019-10-21-python.md')
-rw-r--r--_posts/2019-10-21-python.md99
1 files changed, 99 insertions, 0 deletions
diff --git a/_posts/2019-10-21-python.md b/_posts/2019-10-21-python.md
new file mode 100644
index 0000000..2761bc3
--- /dev/null
+++ b/_posts/2019-10-21-python.md
@@ -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)
+```
+  感觉好难受,每次在网上搜的代码都比我写的好……算了,反正我也是在学习嘛。   
+  后来我听说用欧拉筛法的效率更高……可惜我看完后不太理解……质数算法可真是复杂啊……