Hann Yang 2022-06-21 20:28 采纳率: 100%
浏览 73
已结题

挑战求素数函数的速度!

自定义一个求素数的函数: prime(n) = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ..... ,其中 n = 1,2,3,4,5,6,7,8,9,10......

时间限制:第10万项在9秒以内,第1万项在0.3秒以内(计时硬件:Pentium(R)Dual-Core E5400 + 4GB Ram)

>>> import time
>>> t=time.time();prime(100000);time.time()-t
1299709
8.907615661621094
>>> t=time.time();prime(10000);time.time()-t
104729
0.296400785446167
>>> [prime(i+1) for i in range(10)]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
  • 写回答

3条回答 默认 最新

  • 天元浪子 Python领域优质创作者 2022-06-22 09:34
    关注
    import time
    import numpy as np
    
    def find_prime(top):
        """找出小于top的所有质数"""
        
        prime_list = list() # 空数组,用于存放找到的质素
        mid = int(np.sqrt(top)) # 判断100是否是质数,只需要分别用2,3...等质素去除100,看能否被整除,最多做到100的平方根就够了
        nums = np.arange(top) # 生成0到上限的数组,数组元素的值等于其索引号,相对于python的[0,1,2,3,...]
        nums[1] = 0 # 数组第1和元素置0,从2开始,都是非0的
        
        while True: # 循环
            primes = nums[nums>0] # 找出所有非0的元素
            if primes.any(): # 如果能找到
                p = primes[0] # 则第一个元素为质数
                prime_list.append(p) # 保存第一个元素到返回的数组
                nums[p::p] = 0 # 这个质数的所有倍数,都置为0(表示非质素)
                if p > mid: # 如果找到的质数大于上限的平方根
                    break # 则退出循环
            else:
                break # 全部0,也退出循环
        
        prime_list.extend(nums[nums>0].tolist()) # nums里面剩余的非0元素,都是质数,合并到返回的数组中
        return prime_list # 返回结果
    
    if __name__ == '__main__':
        
        for top in (10_000, 100_000, 1_000_000, 10_000_000):
            t0 = time.time()
            prime_list = find_prime(top)
            t1 = time.time()
            print('查找%d万以内的质数耗时%0.3f秒,共找到%d个质数'%(top//10000, t1-t0, len(prime_list)))
    

    运行结果:

    查找1万以内的质数耗时0.001秒,共找到1229个质数
    查找10万以内的质数耗时0.023秒,共找到9592个质数
    查找100万以内的质数耗时0.653秒,共找到78498个质数
    查找1000万以内的质数耗时14.954秒,共找到664579个质数
    

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
  • A Python 萌新花花 2022-06-21 21:23
    关注
    
    import time
    
    def prime(n):
        a = [2]
        b = a[-1]+1
        while len(a)!=n:
            for i in range(len(a)):
                if b%a[i] == 0:
                    break
                if a[i]**2 >b:
                    a.append(b)
                    break
            b+=1
        return a[-1]
    t = time.time()
    c = prime(10000)
    print(c)
    t = time.time()-t
    print(t)
    
    t = time.time()
    c = prime(100000)
    print(c)
    t = time.time()-t
    print(t)
            
    
    
    评论
  • 对象被抛出 2022-06-21 20:49
    关注

    难点在于不清楚第10万项大致在什么量级, 如果已知这个数不大于N, 可以在[2, N)内用欧拉筛, 这应该是比较快的筛选素数的方法了.

    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月30日
  • 已采纳回答 6月22日
  • 专家修改了标签 6月21日
  • 创建了问题 6月21日

悬赏问题

  • ¥15 matlab有svec这个函数吗?
  • ¥15 无法调用VideoWriter_fourcc
  • ¥15 VB6.0无法加载网页验证码图片到picturebox中,求解。
  • ¥15 C#和GDAL对栅格处理
  • ¥15 我现在有一些关于提升机故障的专有文本数据,量也不多,我在label studio上进行了关系和实体的标注,完成了知识图谱的构造,那么我使用生成式模型的话,我能做哪些工作来写我的论文?
  • ¥15 电脑连不上无线网络如下诊断反馈应该如何操作
  • ¥15 telegram api 使用forward_messages方法转发消息时,目标群组里面会出现此消息来源,如何隐藏?
  • ¥15 关于#tensorflow#的问题:有没有什么方法可以让机器自己学会像素风格的图片
  • ¥15 Oracle触发器字段变化时插入指定值
  • ¥15 docker无法进入容器内部