Eular質數篩法 尤拉篩

2021-09-12 09:04:59 字數 1532 閱讀 7015

相比於時間複雜度為 o(n(lgn)2) 的埃氏篩法,eular 質數篩法就顯得非常短小精悍

尤拉篩的時間複雜度為 o(n),是一種空間換取時間的演算法

一、空間需求

尤拉篩需要兩個陣列:

① prime,用來儲存素數。

② is_prime,用來表示 i (i <= n) 是否為質數。

二、步驟

① memset(is_prime, 1, sizeof(is_prime))

將 is_prime 陣列全部置為 1。

② 外層迴圈loop:for( i = 2 -> n)

遍歷每個數字 i 。

③ 若 i 為質數,那麼將 i 加入 prime 陣列。

④ 內層迴圈loop:for(j = 0 -> prime.length)

不論 i 是否為質數都會進入內層迴圈。

⑤ 若 i * prime[j] > n 則 break 內層迴圈loop。

否則,is_prime[ i * prime[j] ] = 0

把 i * prime[j] 標記為合數。

若 i % prime[j] == 0 則 break 內層迴圈loop,繼續外層迴圈loop。

三、核心

尤拉篩效率這麼高的核心就在於上面的第⑥點,

若 i % prime[j] == 0 則退出內層迴圈loop。

為什麼可以直接退出呢?後面的數就不用繼續篩選了嗎?

是的,當 i % prime[j] == 0 時,說明i = prime[j] * k

對於 prime[j] 後面的元素 prime[next_j],

prime[next_j] * i 將會在之後的篩選中被篩掉,無需重複。

因為prime[next_j] * i = prime[next_j] * (prime[j] * k)

= prime[j] * (prime[next_j] * k)

例如:prime = i = 4

2*4 = 8 被篩 此時 4%2 == 0 break

3*4 = 12 這次不篩

因為 4 = 22, 故 3 * (22) = 2 * (3*2)

在 3 * 2 = 6 = i 時會篩掉12。

int

*prime;

int*is_prime;

void

getprime

(int n)

int cnt =0;

for(

int i =

2; i <= n; i++

)for

(int j =

0; j < cnt; j++

) is_prime[prime[j]

*i]=0;

if(i%prime[j]==0

)}}}

【end】感謝**

Eular質數篩法

任意乙個正整數k,若k 2,則k可以表示成若干個質數相乘的形式。eratosthenes篩法中,在列舉k的每乙個質因子時,我們都計算了一次k,從而造成了冗餘。因此在改進演算法中,只利用k的最小質因子去計算一次k。而在其基礎上改進的eular篩法,其偽 為 isprime true primelist...

數論二 Eular質數篩法

如何去快速得求解 1,n 這個區間內素數的個數呢?自然我們已經知道了如何快速判定乙個數是否是質數,那麼我就直接將 1,n 之間每乙個數判定一次,就可以得到結果。雖然我們已經通過快速素數檢測將每一次判定的時間複雜度降低,但是n個數字的話,總的時間複雜度依舊很高。發現如果乙個數p是質數的話,那麼它的倍數...

數論二 Eular質數篩法

時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述小ho 小hi,上次我學會了如何檢測乙個數是否是質數。於是我又有了乙個新的問題,我如何去快速得求解 1,n 這個區間內素數的個數呢?小hi 你自己有什麼想法麼?小ho 有!我一開始的想法是,自然我們已經知道了如何快速判定乙...