Mayx's Home Page https://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

  1. ---
  2. layout: post
  3. title: Python学习笔记 - 求质数
  4. tags: [Python, 质数, 学习笔记]
  5. ---
  6. 讲真,我酸了……<!--more-->
  7. # 起因
  8. 在学习Python的过程中,我和同学举行了一个比赛,大概内容是用Python做一个时间复杂度最低的质数生成器。
  9. 在学校里就是有个好处,学校网络上知网下论文是免费的,我大概的查了一下,好像用埃氏筛法的效率比较高。
  10. 以前我用Linux Shell也写过一个:
  11. ```shell
  12. #!/system/bin/sh
  13. max=1000
  14. list="2"
  15. rlist="2"
  16. i=3
  17. while [ $i -lt $max ]
  18. do
  19. [ "$(
  20. echo "$list"|while read a
  21. do
  22. [ "$(($i%$a))" == "0" ]&&{
  23. echo "1"
  24. break 1
  25. }
  26. done
  27. )" == "1" ]||c=$i
  28. [ "$bj" == "" -a "$c" != "" ]&&{
  29. [ "$((${c}*${c}))" -gt "$max" ]&&bj="1"
  30. }
  31. [ "$c" == "" ]||{
  32. [ "$bj" == "1" ]||{
  33. list="$list
  34. $c"
  35. }
  36. echo "$c"
  37. }
  38. c=""
  39. i="$(($i+1))"
  40. done
  41. ```
  42. 不过效率极低……因为原生Shell是不支持数组之类的东西,所以其实并不能完全使用埃氏筛法……
  43. # 使用Python做一个
  44. 当然Python还是可以用的,于是我理解了一下,做了一个出来:
  45. ```python
  46. maxprime=100000
  47. rprimeset=set(range(2,maxprime+1))
  48. lprimeset=set()
  49. lastprime=0
  50. while lastprime<=maxprime**0.5:
  51. lastprime=min(rprimeset)
  52. rprimeset=rprimeset-set(range(lastprime,maxprime+1,lastprime))
  53. lprimeset.add(lastprime)
  54. primelist=sorted(list(rprimeset|lprimeset))
  55. print(primelist)
  56. #print(primelist,file=open(__file__[:__file__.rfind("/")]+"/prime.txt",'w+'))
  57. ```
  58. 这个效率确实比Shell做的好太多了,而且看起来也清晰易懂。在我的电脑上,1000000的质数只需要4s就能算出来
  59. # 结局
  60. 不过我后来在某百科上查了一下他们用埃氏筛做的Python版本……然后我就酸了……他们的代码在我的电脑上只需要0.6s就能跑完1000000的质数……而且我估计他们的空间复杂度还比我小……
  61. ```python
  62. # python 原生实现
  63. def primes(n):
  64. P = []
  65. f = []
  66. for i in range(n+1):
  67. if i > 2 and i%2 == 0:
  68. f.append(1)
  69. else:
  70. f.append(0)
  71. i = 3
  72. while i*i <= n:
  73. if f[i] == 0:
  74. j = i*i
  75. while j <= n:
  76. f[j] = 1
  77. j += i+i
  78. i += 2
  79. P.append(2)
  80. for x in range(3,n+1,2):
  81. if f[x] == 0:
  82. P.append(x)
  83. return P
  84. n = 1000000
  85. P = primes(n)
  86. print(P)
  87. ```
  88. 感觉好难受,每次在网上搜的代码都比我写的好……算了,反正我也是在学习嘛。
  89. 后来我听说用欧拉筛法的效率更高……可惜我看完后不太理解……质数算法可真是复杂啊……

Powered by TurnKey Linux.