1.了解什么是质数
质数是指除了1和它本身外再不能被其他数整除的自然数.
2.解题思路:
(1) 设置列表primes用来存储质数. (一开始是空的,标记一个添加一个)
设置列表is_prime, (假设初始时都是质数,标记为True).
(2) 遍历列表is_prime,根据定义可知0和1为非质数,直接标记False
(3) 如果i是质数,则将其标注,并添加(append)到质数列表primes
(4)再次设置变量prime遍历primes中的每一个质数
如果i与当前质数的乘积大于n,视为越界,不做处理,就停止筛,结束本轮遍历
核心细节:
如果i是prime的倍数,说明它的最小质因子是prime, 即: 非质数会被它的最小质因子筛去, 为了防止重复标记非质数,当非质数遇到它的最小质因子,就结束本轮遍历,提高了效率
(5)返回质数列表
(6)进行测试
#定义欧拉筛函数,判断n是否为质数
def euler_sieve(n):
# 初始化质数列表(primes) prime:质数
primes = []
#初始化标记列表(is_prime) 假设所有的数都是质数
is_prime = [True] * (n + 1)
#因为质数是除了1和它本身外再不能被其他数整除的自然数. 0既不是质数也不是合数
is_prime[0] = is_prime[1] = False
#遍历(2, n+1) 包左不包右
for i in range(2, n + 1):
if is_prime[i]: #如果i是质数
primes.append(i) #将i添加到质数列表
#设置变量prime遍历primes中的每一个元素,用已经找到的质数去筛选掉i的倍数
#核心细节: 用已经找到的质数去筛选掉i的倍数
for prime in primes:
#核心细节:如果i与当前质数的乘积大于视为越界,不做处理,结束本轮遍历
if i * prime > n:
break
#并将其标注为非质数
is_prime[i * prime] = False
#核心细节:如果i是prime的倍数,说明它的最小质因子是prime, 即: 非质数会被最小因子筛去, 结束本轮遍历,防止重复标记非质数,提高了效率
if i % prime == 0:
break
#返回质数列表
return primes