求素數的幾種方法

2021-10-10 00:03:54 字數 2047 閱讀 6254

素數,也稱為質數,其只能被1或者自身整除的自然數(不包括1)。換而言之,只有兩個正因數的自然數稱為素數。

與之相對的比1大但不是素數的自然數稱為合數。1和0既不是素數也不是合數,合數由若干個質數相乘得到。

顯然根據定義就能判斷乙個數n是否為素數,具體的,對其從2到sqrt(n)進行除法,判斷是否存在餘數為0的情況,存在即認為n為合數,否則即為素數(這裡臨界的根號n是因為,對於n=p×q,顯然p和q至少有乙個小於根號n)。

bool prime(int n)

return 1;

}

埃拉託斯特尼篩法,簡稱埃氏曬,是一種用來求自然數n以內的全部素數。

他的基本原理是,如果我們要獲得小於n的所有素數,那就把不大於根號n的所有素數的倍數剔除。

埃氏曬的原理很容易理解,乙個合數,必然可以表示成,乙個自然數 i 和乙個素數的乘積。因此我們找到乙個素數後,把他小於n的倍數全部標記為合數,這就是我們要做的

bool flag[n_max];//0為素數 1為合數

int primes[n_max];

void prime(int n)

} }}

值得注意的是,其中內層迴圈的起始點為 i×i,這是因為 i × (2 至( i –1))在之前的迴圈中,已經被篩去(因為2 至( i –1)均小於i)。觀察被篩掉的資料,我們可以發現,乙個合數,可能會被篩掉多次,例如,30 = 2 * 15 = 3 * 10 = 5 * 6,所以30 就至少被2,3,5這三個質數分別篩過了,這個地方就會造成時間的浪費。

該方法保證每個合數僅被篩一次,其依據如下:

每個合數n都可以表示成這種形式,其中factormax表示n的最大因數,並且剩下的這個 p 滿足:

它是乙個素數.

它比 factormax的所有因數都要小.

即 p是 n 的最小素因數.

證明如下:

假設p為合數,則p = p1 * p2 * ···· * pn,其中,p1fatory,所以和factory是n的最大的因數矛盾,故假設不成立

假設p大於factory的某個因數,不妨設p>p1因為 factory = p1 * p2 * ···· * pn 因此 p * p2 * ··· * pn 必然大於factory 所以和factory是n的最大因數矛盾,故假設不成立

假設有乙個素數表 prime[n]和乙個是否為合數的標記表 flag[n] (定義 true表示合數)。我們每次列舉乙個數 i,判斷它是否標記過,如果是,那麼存入 prime[n] ,否則不存。接下來我們標記由 i (不論它是素數與否)產生的數 n= i⋅prime[n]為合數,因為顯然質數和另乙個數(>2 )相乘為合數。

根據以上結論,我們對於乙個數,把它作為另乙個數最大因子,那麼顯然可以根據已有的質數表產生一些合數. 並且我們知道這些合數顯然只有一種產生方法(只有乙個 factormax)那麼我們每次根據列舉到的 i 只要判定prime[n]是不是最小素因數就可以保證列舉的量不多不少。

在判斷 i % prime[n] == 0 之前的素數均為對應合數的最小素因數,其後的素數均不是。這是因為 i 可以分解為 prime[n] × k,因此對於後面的更大的素數prime[n+1]來說,其對應的合數prime[n+1] × i = prime[n+1] × prime[n] × k,其中 prime[n]小於prime[n+1],故prime[n+1]不是該合數的最小素因數。

bool flag[n_max];//0為素數 1為合數

int primes[n_max]; //存放找到的素數

void euler_prime(int n)

}}

Java求素數(質數)的幾種方法

比1大的整數中,除了1和它本身以外,不再有別的因數,這種整數叫做質數或素數 要判斷x是否為質數,就從2一直嘗試到x 1的做法效率是最差的!其實只要從2一直嘗試到 x,就可以了。因為因數都是成對出現的。比如,100的因數有 1和100,2和50,4和25,5和20,10和10。看出來沒有?成對的因數,...

求前K個素數的幾種方法

現在有乙個問題,輸入k,求前k個素數或者說求第k個素數。常規的想法,就是從0開始往後遍歷,是素數就存起來,直到找到第k個。我們這裡介紹三種篩選素數的方法 埃式篩法 線性篩法 6倍數判別法。include include include using namespace std typedef long...

求素數的幾種方法(暴搜法和篩選素數法)

參考自該篇部落格 參考自該篇部落格 其分為兩種,一種是直接for迴圈,另一種是建立在數學思想上的平方根迴圈。第二種演算法時間複雜度明顯優於第一種。也就是最簡單直接的for迴圈,判定這個數是否能被除1 和其本身以外的整數整除。這個也是基於for迴圈的一種方式,比上面那種方法稍微快了一點。當n的數值較大...