說明:
除了自身之外,無法被其它整數整除的數稱之為質數,在自然數中,除了1和此整數自身外,不能夠被其他自然數整除的數,稱之為質數。要求質數很簡單,但如何快速的
求出質數則一直是程式設計人員與數學家努力的課題,
在這邊介紹一個着名的Eratosthenes求質
數方法。
解法:
首先知道這個問題可以使用回圈來求解,將一個指定的數除以所有小於它的數,若可以
整除就不是質數,然而如何減少回圈的檢查次數?如何求出小於N的所有質數?
首先假設要檢查的數是N好了,則事實上只要檢查至N的開根號就可以了,道理很簡單,假設
A*B = N,如果A大於N的開根號,則事實上在小於A之前的檢查就可以先檢查到B這個數可以整
除N。不過在程式中使用開根號會精確度的問題,所以可以使用i*i <= N進行檢查,且執行更快。
再來假設有一個篩子存放1~N,例如:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ........ N
先用2的去做篩選,從4=22 開始,篩去2的倍數,循環步長為2: 2 3 5 7 9 11 13 15 17 19 21 ........ N
再用3的去做篩選,從9=32 開始,篩去3的倍數,循環步長為3: 2 3 5 7 11 13 17 19 ........ N
再用5的去做篩選,再用5的去做篩選,再用11的去做篩選........,如此進行到最后留下的
數就都是質數,這就是Eratosthenes篩選方法(Eratosthenes Sieve Method)。
*/
public class Eratosthenes { /** * @param args */ public static void main(String[] args) { int N = 100; int i = 0, j = 0 , count = 0; int prime[] = new int[N + 1]; //初始化數據 for (i = 2; i <= N; i++) { prime[i] = 1; } //循環1(N 開方 次) for (i = 2; i * i <= N; i++) { if (prime[i] == 0) { count++; continue; } //循環2(N/i 次) 篩選被i整除的數 for (j = i * i; j <= N; j = j + i) { prime[j] = 0; count++; } } System.out.println("Times of calculation : " + count); j=0; for (i = 2; i <= N; i++) { if (prime[i] == 1) { System.out.print("\t"); System.out.print(i); j++; if(j % 10 == 0){ System.out.println(); } } } } }
循環次數 O(N):
N | 進入循環的次數 | 循環次數/N |
100 | 109 | 1.09 |
1000 | 1430 | 1.43 |
10000 | 17055 | 1.70 |
100000 | 193328 | 1.93 |
1000000 | 2122879 | 2.12 |
10000000 | 22852766 | 2.28 |