素數表獲取的樸素演算法與埃氏篩法

2021-09-28 21:39:31 字數 1847 閱讀 4373

可以先來看看一道簡單的題目:

試列印 1 - n 範圍內的素數表。

分析:

好,我們從1~n進行列舉,判斷每個素數是否是素數,如果是素數,則加入素數表。那麼這個演算法的時間複雜度是多少呢?可以看到,列舉部分的複雜度是o(n),而判斷素數的演算法是o(n^1/2),因此總複雜度是o(n * n ^1/2)。但是顯然這個複雜度對n超過10 ^ 5的情況來說是有問題的。因為對一般的oj系統來說,一秒能承受的運算次數大概是10 ^ 7 ~ 10 ^ 8,而程式一般要求1s內進行。自己可以估算一下。

給出**(以求解100以內的所有素數為例):

#include

#include

bool

isprime

(int n)

return

true;}

int prime[

101]

,pnum =0;

//prime陣列存放素數,pnum為陣列下標

bool p[

101]=;

void

find_prime()

}}intmain()

}

好,我們接著上面講的繼續講下去,既然樸素演算法的時間複雜度不是很令人滿意,那麼是否有更好的演算法呢?

「埃氏篩法」就是眾多篩法中簡單的一種,可以達到o(nloglogn)的時間複雜度。所謂「篩法」關鍵就在於乙個篩字。從小到大列舉所有數,對每乙個素數,篩去它的所有倍數,剩下的都是素數了。這聽起來好像是在逗人???你還不知道哪個數是素數呢,簡直就是悖論。

先來看乙個例子吧:求1~15中的所有素數。

分析:

至於「篩」這個動作的實現,可以使用乙個bool型陣列p來標記,如果a被篩掉,那麼p[a]為true,否則,p[a]為false。在程式開始時可以初始化p陣列為false。

給出上述題目的**(埃氏篩法):

#include

const

int maxn =

101;

int prime[maxn]

, pnum =0;

bool p[maxn]=;

//初始化p陣列全部為false,如果a被篩掉,那麼p[a]為true;否則,p[a]為false

void

find_prime()

}}}int

main()

}

令pi表示第 i 個素數,現任意給兩個正整數m<=n<=10^4,請輸出pm到pn的所有素數。

輸入格式:

輸入在一行中給出m和n,其間以空格分隔。

輸出格式:

輸出從pm~pn的所有素數,每10個數字佔一行,其間以空格分隔,但行末不能有空格。

給出**(埃氏篩法和樸素都可以,這裡給出的是埃):

//埃氏篩法 

#include

const

int maxn =

1000001

;int prime[maxn]

, num =0;

bool p[maxn]=;

//初始化p陣列全部為false,如果a被篩掉,那麼p[a]為true;否則,p[a]為false

void

find_prime

(int n)}}

}int

main()

return0;

}

埃氏篩法 素數篩

埃式篩法 給定乙個正整數n n 10 6 問n以內有多少個素數?做法 做法其實很簡單,首先將2到n範圍內的整數寫下來,其中2是最小的素數。將表中所有的2的倍數劃去,表中剩下的最小的數字就是3,他不能被更小的數整除,所以3是素數。再將表中所有的3的倍數劃去 以此類推,如果表中剩餘的最小的數是m,那麼m...

素數 埃氏篩法

題目 求2 100以內的素數。素數 prime number 又稱質數,是指乙個大於1的自然數,除了1和它本身外,不能被整除以其他自然數。解法一 根據素數的定義,即用該數除比其小的數 1除外 都不能除盡,即為素數 public class prime if i n system.out.print ...

快速求素數表 埃氏篩法與尤拉篩法

尤拉篩法 素數的定義 素數就是除了1和本身之外沒有其他的約數,所以有約數的都不是素數。因此,埃氏篩法的思想就是 先去掉2的倍數,再去掉3的倍數,再去掉4的倍數,依此類推,直到最大數小於最後乙個標出的素數的平方,那麼剩下的序列中所有的數都是素數。o nloglogn 時間複雜度的證明戳此鏈結 incl...