輸出指定範圍內的素數(質數)
阿新 • • 發佈:2019-02-13
這裡最近看到了一個方法Sieve of Eratosthenes的方法,突然覺得以前的方法太坑了,我以前都是直接使用窮舉法。
先說一下我理解的原理:
首先任何一個大於2的合數都等於一個素數乘以一個正整數,根據這個就可以開始推下面的方法。
問題:求1-n的所有素數
步驟:
1、建立一個n大小的陣列A,將1標記為非素數,將2標記為素數,然後將3-n中所有的2的倍數標記為合數,同時將2賦值給K;
2、判斷A中大於K的數是否已經全部被標記或者K等於n,如果是空跳到第4步;
3、求得A中最小的未標記的數m,將m標記為素數,將B中所有m的倍數標記為合數,同時將m賦值給K,返回第2步;
4、輸出陣列A中所有素數。
下面貼出程式碼:
#include <stdio.h> #include <Windows.h> #define UNLABELED 0 //未標記 #define PRINE 1 //素數 #define COMPOSITE 2 //合數 #define NOPRINE 3 //非素數 #define SIZE 100 int main() { int i = 0; //i表示整數和對應的下標 int j = 0; //j表示正要處理的素數j之前的已處理j之後的未處理 int k = 0; //k表示正在處理的j的倍數從2開始到 j * k < SIZE int *p = NULL; //控制迴圈 int a[SIZE + 1] = { 0 }; //下標表示整數內容判斷是否為素數 for (p = a; p < a + SIZE; ++p) { //初始化陣列全是UNLABELED *p = UNLABELED; } p = NULL; a[0] = a[1] = NOPRINE; //設定前面兩個不是素數的數的狀態為NOPRINE i = 2; while (i < SIZE + 1) { //判斷是否未標記,找到下一個素數 if (a[i] == UNLABELED) { j = i; a[i++] = PRINE; } else { //已經標記了繼續i++向下走 i++; continue; } for (k = 2; j * k < SIZE; ++k) { //處理素數的倍數 a[j * k] = COMPOSITE; } } for (p = a; p < a + SIZE; ++p) { //打印出素數 if (*p == PRINE) { printf("%8d", p - a); } } p = NULL; printf("\n"); system("pause"); return 0; }
我把執行結果複製一遍吧,之前沒仔細看了,計算到一千,但是999沒有訪問到,所以1000的時候999打出來了,100的時候99打出來了,多謝指點了。
一個是1-100
這個是1-1000
-_-.