Python入门经典算法学习-求素数

经典算法学习–求素数


求100以内素数

    

什么是素数?

素数的特性,只能被1和自己整除

优化方法:

被除数:步长去偶,后去5的倍数

除数:起始去2,步长去偶,选取中值平方根,

合数特性:每个合数都能拆解成素数的乘积,利用这个们可以使用素数作为除数,比奇数更精简了,这里需要列表复用素数。

孪生素数特性:2,3之后的每个素数都是6的倍数相邻数。

最后将以上优化点合一,测试效率如何。


  1. 基本求解
        按照定义,从1 开始 到 n-1都没有找到整除它的数,就是质数。
# %%timeit

# 算法1

n = 100
count = 0 
for x in range(2, n):       # 被除数空间
    for i in range(2, x):   # 除数空间
        if x % i == 0:
            break
    else:
        count += 1  #
        print(x, end=' ')
print('\n', count) 
print('-' * 30)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 
 25
------------------------------

    这样我们使用素数基本定义对于100以内素数的求解,就可以说达成了基本要求。

    但是呢,很明显这个方法过于原始,以至于做了很多无用功而导致算法效率低下,存在很多的可以优化提升的地方。


  1. 基本算法优化

    一般来讲在这里我们很容易想到,用折半思想进行优化,在被除数区间中,我们很容易注意到,偶数一定会被2整除,因此一定不是素数,也就是说素数一定是个奇数,我们被除数区间的偶数全部去掉,那么我们算法理论上效率提升了一倍。

    那么除数区间是不是也可以去除偶数呢?这当然可以,每个偶数的公约数都有一个2,也就是说能整除偶数的必然也是个偶数,所以我们可以再继续从除数空间剔除偶数。

    那么如何实现除数空间去偶呢?我使用range函数生成一个可迭代对象,而这个range函数提供的步长step刚好可以实现这一点,通过把步长置为2,我们可从一个奇数直接跳到下一个奇数,如3,5,7,9…。

    除此之外,我们不难发现一旦除数大于‘被除数的一半’而没有数可以整除它,那么再对后面的除数取模也已经是无济于事了,只能是平白多了无用功。这里的‘被除数的一半’经过计算我们不难得出,指的是其平方根,例如:25 = 5 * 5 ,一旦25过了算术平方根5,那么就相当于对之前的除过的数再一次对称计算。因此我们取到算数平方根作为‘中点’。

    这里有一点需要注意,range函数是左闭右开区间,且只接受int整型作为参数,因此我们需要测试边界问题,一般去情况下都会在计算值的基础上+1。

# %%timeit
# 算法2

n = 100
count = 1
for x in range(3, n, 2):
    for i in range(3, int(x**0.5)+1, 2):  ## 平方根折半优化
        if x 
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值