python 埃氏筛法判断一个数是否为素数

菜鸡一枚欢迎指正

目录

特点

思路

优化

代码


特点

合数都是被他的最小素数因子筛去的

思路

定义两个list : status : 表示整数状态,一开始除0,1外都默认为素数,合数标记为False prime:存放素数

遍历2->n 如果status为True,表示当前为i为素数,加入到prime数组。然后遍历prime列表pj把i*pj标记为合数。

注意:当i为合数,p[j]为i的最小素因子,那么标记完status[i*p[j]] 后就结束对于prime的遍历。例如:当i为4时,此时prime=[2,3], 标记status[i * 2]为False,因为2为4的最小素因子,所以此时结束对prime的遍历

当i大于n的一半后,i*prime[j]都大于n,所以无需再标记合数只需添加后续的素数即可

优化

由于偶数肯定不是素数所以可以只考虑奇数的情况

代码

#判断一个数是否为素数
def is_prime(n):#返回的是最小素因子,如果为素数返回0
    if n == 0 or n==1:
        return 1
    if n == 2:
        return 0
    if n%2==0:#偶数不是素数
        return 2
    m = int(n ** 0.5)
    status = [True for _ in range(int(m / 2) + 1)]  # 3,5,7,9,11,13,15,17,19,21,23
    prime = []
    for i in range(3, m + 1, 2):  
        if status[int((i - 3) / 2)]:
            if n % i ==0:
                return i
            prime.append(i)
        for pj in prime:  # 遍历prime
            if pj * i > m:  # 越界结束遍历
                break
            status[int((pj * i - 3) / 2)] = False
            if i % pj == 0:#p[j]为i的最小素因子,此时结束遍历
                break
    return 0

def prime_list(n):
    if n == 0 or n==1:
        return []
    if n == 2:
        return [2]
    m = int(n ** 0.5)
    status = [True for _ in range(int(n/2) + 1)]  # 3,5,7,9,11,13,15,17,19,21,23
    prime = []
    for i in range(3, n+1, 2):  # 遍历3-m,跳过所有偶数
        if status[int((i - 3) / 2)]:
            prime.append(i)
        for pj in prime:  # 遍历prime
            if pj * i > n:  # 当i大于n的一半后,i*prime[j]都大于n,所以无需再标记合数只需添加后续的素数即可
                break
            status[int((pj * i - 3) / 2)] = False
            if i % pj == 0:  # p[j]为i的最小素因子,此时结束遍历
                break
    return [2]+prime

n=int(input("请输入一个整数:"))
pr=is_prime(n)
if pr:
    print("{0}不是素数,最小素因子为{1}".format(n,pr))
else:
    print("{0}是素数".format(n))
pl=prime_list(n)
print("1到{0}的素数有{1}".format(n,pl))



  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值