【发布时间】:2018-11-10 13:33:26
【问题描述】:
Python 3 生成从1到n的素数。如何提高效率,复杂度如何?
输入:一个数字,最大值(一个大数字) 输出:从 1 到最大值的所有素数 输出为列表形式,为 [2,3,5,7,11,13,.......] 代码试图以一种有效的方式(最低的时间复杂度)来执行这个任务。
from math import sqrt
max = (10**6)*3
print("\nThis code prints all primes till: " , max , "\n")
list_primes=[2]
def am_i_prime(num):
"""
Input/Parameter the function takes: An integer number
Output: returns True, if the number is prime and False if not
"""
decision=True
i=0
while(list_primes[i] <= sqrt(num)): #Till sqrt(n) to save comparisons
if(num%list_primes[i]==0):
decision=False
break
#break is inserted so that we get out of comparisons faster
#Eg. for 1568, we should break from the loop as soon as we know that 1568%2==0
i+=1
return decision
for i in range(3,max,2): #starts from 3 as our list contains 2 from the beginning
if am_i_prime(i)==True:
list_primes.append(i) #if a number is found to be prime, we append it to our list of primes
print(list_primes)
我怎样才能加快速度?我在哪里可以改进? 这段代码的时间复杂度是多少?哪些步骤效率低? Eratosthenes 筛在哪些方面比这更有效?
为最初的几次迭代工作:-
- 我们有一个包含素数的
list_primes。它最初只包含 2 个。 - 我们转到下一个数字 3。3 能被
list_primes中的任何数字整除吗?不!我们将 3 附加到list_primes。现在,list_primes=[2,3] - 我们转到下一个数字 4。4 能被
list_primes中的任何数字整除吗?是(4 可被 2 整除)。所以,我们什么都不做。现在list_primes=[2,3] - 我们转到下一个数字 5。5 能被
list_primes中的任何数字整除吗?不!我们将 5 附加到 list_primes。现在,list_primes=[2,3,5] - 我们转到下一个数字 6。6 能被 list_primes 中的任何数字整除吗?是的(6 可以被 2 整除,也可以被 3 整除)。所以,我们什么都不做。现在
list_primes=[2,3,5] - 等等……
【问题讨论】:
-
FWIW,我会从循环条件中删除
sqrt(num)的计算。计算成本很高,而且不会改变,所以只计算一次。也许它可以自动优化,但我不会指望它。 -
是的,有道理。谢谢
标签: algorithm time-complexity primes sieve-of-eratosthenes