任意乙個正整數k,若k≥2,則k可以表示成若干個質數相乘的形式。
eratosthenes篩法中,在列舉k的每乙個質因子時,我們都計算了一次k,從而造成了冗餘。因此在改進演算法中,只利用k的最小質因子去計算一次k。
而在其基礎上改進的eular篩法,其偽**為:
isprime = trueprimelist =
primecount = 0
for i = 2
.. n
if isprime[i] then
primecount = primecount + 1
primelist[ primecount ] =i
end if
for j = 1
.. primecount
if (i * primelist[j] >n) then
break
end if
isprime[ i * primelist[j] ] = false
if (i %primelist[j]) then
break
end if
end if
end for
與eratosthenes篩法不同的是,對於外層列舉i,無論i是質數,還是是合數,我們都會用i的倍數去篩。但在列舉的時候,我們只列舉i的質數倍。比如2i,3i,5i,...,而不去列舉4i,6i...,原因我們後面會講到。
此外,在從小到大依次列舉質數p來計算i的倍數時,我們還需要檢查i是否能夠整除p。若i能夠整除p,則停止列舉。
eular篩法可以保證每個合數只會被列舉到一次,時間複雜度為o(n)。當n越大時,其相對於eratosthenes篩法的優勢也就越明顯。
下面是實現**:
int numprime(intn)
int primelist[100000
];
int primecount = 0
;
for(int i = 2; i<= n; i++)
for(int j = 1; j<= primecount; j++)
}//for(int i = 1; i<= primecount; i++) cout << primelist[i] << endl;
return
primecount;
}
Eular質數篩法 尤拉篩
相比於時間複雜度為 o n lgn 2 的埃氏篩法,eular 質數篩法就顯得非常短小精悍。尤拉篩的時間複雜度為 o n 是一種空間換取時間的演算法。一 空間需求 尤拉篩需要兩個陣列 prime,用來儲存素數。is prime,用來表示 i i n 是否為質數。二 步驟 memset is prim...
數論二 Eular質數篩法
如何去快速得求解 1,n 這個區間內素數的個數呢?自然我們已經知道了如何快速判定乙個數是否是質數,那麼我就直接將 1,n 之間每乙個數判定一次,就可以得到結果。雖然我們已經通過快速素數檢測將每一次判定的時間複雜度降低,但是n個數字的話,總的時間複雜度依舊很高。發現如果乙個數p是質數的話,那麼它的倍數...
數論二 Eular質數篩法
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 小hi,上次我學會了如何檢測乙個數是否是質數。於是我又有了乙個新的問題,我如何去快速得求解 1,n 這個區間內素數的個數呢?小hi 你自己有什麼想法麼?小ho 有!我一開始的想法是,自然我們已經知道了如何快速判定乙...