亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

列出N以下所有素數的最快方法

列出N以下所有素數的最快方法

列出N以下所有素數的最快方法這是我能提出的最佳算法。def get_primes(n):    numbers = set(range(n, 1, -1))    primes = []    while numbers:        p = numbers.pop()        primes.append(p)        numbers.difference_update(set(range(p*2, n+1, p)))    return primes>>> timeit.Timer(stmt='get_primes.get_primes(1000000)', setup='import   get_primes').timeit(1)1.1499958793645562可以做得更快嗎?此代碼有一個缺陷:由于numbers是無序集,因此無法保證numbers.pop()從集中刪除最小數字。然而,它對某些輸入數字起作用(至少對我而言):>>> sum(get_primes(2000000))142913828922L#That's the correct sum of all numbers below 2 million>>> 529 in get_primes(1000)False>>> 529 in get_primes(530)True
查看完整描述

3 回答

?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

更快,更內存的純Python代碼:

def primes(n):
    """ Returns  a list of primes < n """
    sieve = [True] * n    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return [2] + [i for i in range(3,n,2) if sieve[i]]

或者從半篩開始

def primes1(n):
    """ Returns  a list of primes < n """
    sieve = [True] * (n//2)
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i//2]:
            sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1)
    return [2] + [2*i+1 for i in range(1,n//2) if sieve[i]]

更快,更內存的numpy代碼:

import numpydef primesfrom3to(n):
    """ Returns a array of primes, 3 <= p < n """
    sieve = numpy.ones(n//2, dtype=numpy.bool)
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i//2]:
            sieve[i*i//2::i] = False
    return 2*numpy.nonzero(sieve)[0][1::]+1

從篩子的三分之一開始變化更快:

import numpydef primesfrom2to(n):
    """ Input n>=6, Returns a array of primes, 2 <= p < n """
    sieve = numpy.ones(n//3 + (n%6==2), dtype=numpy.bool)
    for i in range(1,int(n**0.5)//3+1):
        if sieve[i]:
            k=3*i+1|1
            sieve[       k*k//3     ::2*k] = False
            sieve[k*(k-2*(i&1)+4)//3::2*k] = False
    return numpy.r_[2,3,((3*numpy.nonzero(sieve)[0][1:]+1)|1)]

上述代碼的(難以編碼)純python版本將是:

def primes2(n):
    """ Input n>=6, Returns a list of primes, 2 <= p < n """
    n, correction = n-n%6+6, 2-(n%6>1)
    sieve = [True] * (n//3)
    for i in range(1,int(n**0.5)//3+1):
      if sieve[i]:
        k=3*i+1|1
        sieve[      k*k//3      ::2*k] = [False] * ((n//6-k*k//6-1)//k+1)
        sieve[k*(k-2*(i&1)+4)//3::2*k] = [False] * ((n//6-k*(k-2*(i&1)+4)//6-1)//k+1)
    return [2,3] + [3*i+1|1 for i in range(1,n//3-correction) if sieve[i]]

不幸的是,pure-python不采用更簡單,更快速的numpy方式進行賦值,并且len()在循環內調用[False]*len(sieve[((k*k)//3)::2*k])太慢。所以我不得不即興改正輸入(避免更多的數學運算)并做一些極端(和痛苦)的數學魔術。

就個人而言,我認為numpy(這是如此廣泛使用)不是Python標準庫的一部分是一種恥辱,并且Python開發人員似乎完全忽略了語法和速度的改進。


查看完整回答
反對 回復 2019-05-27
  • 3 回答
  • 0 關注
  • 1217 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號