素數快速求法 篩法求素數

2021-07-30 14:44:18 字數 1657 閱讀 1902

在做題的過程中,我們會遇到一些需要求素數的要求,如果對於資料範圍很小的資料,我們有最簡單但是最耗時間的雙for迴圈巢狀法。下面舉個例子。

question : get the primes from 1 to 100 and print them.

/**

* 素數求法 基礎for迴圈法

*/#include #include using namespace std;

int main( )

printf("%d\n",i);

}return

0;}

這樣之後就求出來了1 到100的素數,很簡單但是很耗時間啊 一般不用。

好,下面介紹第二種求素數的方法 ———篩法求素數

/**

* 一般線性篩法素數

*/void make_prime()

return;

}

解釋

篩法求素數的思想主要是先將數字假設為素數。用prime標記陣列來標記為1表示這個數是素數。但是要注意prime[0] 和 prime[1] 不用假設為素數。 然後就是從2開始。只要prime陣列不是0,就執行for迴圈的遍歷,然後將當前的數字k乘以本身,然後更新prime陣列為false。然後k = k + i;

這裡用到素數乙個性質 :乙個素數每次乘以2得到的數字就是合數(合數的意思是除了1和本身之外還可以被其他數字整除,和素數相反。)

我們可以在for迴圈裡面用 看= i*2 這個條件的 但是仔細觀察用i*i更快一點。這點自己可以在紙上畫一畫就了解了,說的話很容易暈,在紙上畫一畫很容易理解的。

這樣,我們就用篩法將合數都標記為false了。然後將標記是素數的數字輸出就可以得到範圍裡面的素數了。

上面的一般線性篩法求素數以及可以處理素數的問題了,如果第二種看的不太懂的話,建議先不要看優化的快速篩法求素數。容易亂。其實這樣就是當模板用的。找個題目用一下就會了。

優化:快速篩法求素數

其實我們可以發現,在一般的線性的篩法中,我們對範圍內的數字篩了很多次,造成了時間的浪費,那麼我們可不可以優化呢?當然是可以的。

/**

* 快速篩法求素數 不考慮偶數 範圍直接減半

*/half=size/2; //資料規模為size

int sn = (int) sqrt(size);

for (i = 0; i < half; i++)

p[i] = true;// 初始化全部奇數為素數。p[0]對應3,即p[i]對應2*i+3

for (i = 0; i < sn; i++)

}

//素數都存放在 p 陣列中,p[i]=true代表 i+i+2 是素數。

//舉例,3是素數,按3*3,3*5,3*7...的次序篩選,因為只儲存奇數,所以不用刪3*4,3*6....

好了 素數的問題就說到這裡了 我回去整理二分法的演算法

拜拜了 各位

有什麼不對的地方 歡迎指正 謝謝

快速篩法求素數

stack queue的部落格 求素數是程式設計比賽中經常遇到的問題,最基本的方法是通過素數的定義直接判斷,只能被1和它本身整除的數就是素數了。這種方法適合判斷單個數是否為素數,當要求乙個範圍內素數而這個範圍又比較大時,這種方法就不太使用了,甚至程式要執行幾分鐘才能算出結果。篩法的思想是去除要求範圍...

快速篩法求素數

篩法的思想是去除要求範圍內所有的合數,剩下的就是素數了,而任何合數都可以表示為素數的乘積,因此如果已知乙個數為素數,則它的倍數都為合數。1 include2 using namespace std 3 define max 100000 4long long su max cnt 5bool isp...

素數篩法求素數

素數篩類似於打表標記,預先處理掉非素數的數,即素數的倍數 任意非素數都可以由幾個素數相乘得到 於是效率比暴力求解快得多。埃氏篩法的效率為o n loglog n 簡單易懂,但是會重複標記,比如當i為2時,6會被標記掉,然而當i為3時,6又會被重複標記,這樣的重複訪問加大了時間複雜度,於是有了尤拉篩。...