zoukankan      html  css  js  c++  java
  • 厄拉多塞筛法的 Python 实现以及复杂度计算

    想要得到一个不大于N的数所有素数,可以先找到不超过根号N的所有素数,设2 = p1 < p2 < ......<pk ≤√N,然后在2,3,4......N里面进行下面的操作:

    留下p1 = 2,把p1的倍数全部划掉,

    再留下p2 ,把p2 的倍数全部划掉,

    继续这一过程,直到留下 (p_k),把 (p_k) 的倍数全部划掉,

    最后留下来就是不超过N的全体素数。

    样例


    image-20210706165953719

    剩余的数就是小于等于30的所有素数,即 2,3,5,7,11,13,17,19,23,29

    Python 实现

    算法思想来自于上面的介绍,但是并不是严格遵循上面的步骤:

    def eladuosai(n):
        l = list(range(1,n+1))
        l[0] = 0
        for i in range(2,n+1):
            if l[i-1] != 0 :
                for j in range(i*2,n+1,i):
                    l[j-1] = 0
        result = [x for x in l if x != 0]
        return result
    

    求小于等于N的所有素数的普通算法:

    def sushu(n):
        result = []
        for x in range(2,n+1):
            for y in range(2,x):
                if x % y == 0:
                    break
            else:
                result.append(x)
        return result    
    

    时间对比,使用timeit模块测试两个方法的时间,当取n为10000的时候有如下结论:

    t1 = timeit.Timer('sushu(10000)',setup='from __main__ import sushu')
    t2 = timeit.Timer('eladuosai(10000)',setup='from __main__ import eladuosai')
    print('厄拉多塞筛法的时间 ',t2.timeit(1))
    print('普通函数的时间 : ',t1.timeit(1))
    

    厄拉多塞筛法的时间 0.005523548190824634
    普通方法的时间 : 0.7220688150193577

    可以看出厄拉多塞筛法的运行时间比普通方法的时间要少很多。


    厄拉多塞筛法的时间复杂度

    O(NloglogN)数的是算术运算的次数。当N很大时,每个算术运算不一定在常数个指令周期内完成。不妨假设算术运算的时间复杂度是O(logN),也就是存储N所需要的空间。

    此时厄拉多塞筛法的时间复杂度是O(NloglogN) * O(logN) = O(NlogNloglogN)

    而这个loglogN又是怎么来的呢?厄拉多塞筛法找到k的时候需要标记O(N/k)个数为合数。因此一共需要

    标记 (sum_{ple N}frac{N}{p} = N*sum_{ple N}frac{1}{p}) 次,其中p <= N表示所有小于等于N的素数。这就是N乘以小于等于N的素

    数的倒数之和。

    右边是O(N)*O(loglogN) = O(NloglogN)的。

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    Selenium IDE的第一个测试用例——路漫长。。。
    selenium学习第三天,新建一个测试用例(运行失败)。
    Selenium学习第二天,了解Selenium工作模式与学习Selenium需要具备的知识与工具。
    了解Selenium与自动化测试第一天“云里雾里”
    javascript冷知识
    HTTP权威指南学习心得
    (六)Linux进程调度-实时调度器_学习笔记
    (五)Linux进程调度-CFS调度器_学习笔记
    (四)Linux进程调度-组调度及带宽控制_学习笔记
    (三)Linux进程调度器-进程切换_学习笔记
  • 原文地址:https://www.cnblogs.com/RioTian/p/14977810.html
Copyright © 2011-2022 走看看