題目:寫一個程式,找出前N個素數。比如N為100,則找出前100個素數。分析最基本的想法就是對1到N得每個數進行判斷,如果是素數則輸出。一種改進的方法是不需要對1到N所有的數都進行判斷,因為偶數肯定不是素數,而奇數可能是素數,可能不是。2,3,5都是素數,這可以直接得到。然後我們可以跳過2與3的倍數,即對於6n,6n+1, 6n+2, 6n+3, 6n+4, 6n+5,我們只需要判斷6n+1與6n+5是否是素數即可。判斷某個數m是否是素數,最基本的方法就是對2到m-1之間的數整除m,如果有一個數能夠整除m,則m就不是素數。判斷m是否是素數還可以進一步改進,不需要對2到m-1之間的數全部整除m,只需要對
2到根號m之間的數整除m就可以。如用2,3,4,5...根號m整除m。其實這還是有浪費,因為如果2不能整除,則2的倍數也不能整除,同理3不能整除則3的倍數也不能整除,因此可以只用
2到根號m之間小於根號m的素數去除即可。解法1:基本解法給出一個最基本的解法就是預先可得2,3,5為素數,然後跳過2與3的倍數,從7開始,然後判斷11,然後判斷13,再是17...規律就是從5加2,然後加4,然後加2,然後再加4。如此反覆即可,如所示,只需要判斷7,11,13,17,19,23,25,29...這些數字。對這些數進行判斷,如果是素數則輸出。判斷是否是素數採用改進後的方案,即對2到根號m之間的數整除m來進行判斷。需要注意一點,不能直接用根號m判斷,因為對於某些數字,比如121,開根號後得到的不一定是11,可能是10.999999,所以最好使用乘法判斷,如代碼中所示:
#include <stdio.h>#define MAXSIZE 100#define YES 1#define NO 0int main(void){ int prime[MAXSIZE]; /* array to contains primes */ int gap = 2; /* increasing gap = 2 and 4 */ int count = 3; /* no. of primes */ int may_be_prime = 5; /* working variable */ int i, is_prime; prime[0] = 2; /* Note that 2, 3 and 5 are */ prime[1] = 3; /* primes. */ prime[2] = 5; while (count < MAXSIZE) { /* loop until prime[] full*/ may_be_prime += gap; /* get next number */ gap = 6 - gap; /* switch to next gap */ is_prime = YES; /* suppose it were a prime*/ for (i = 2; prime[i]*prime[i] <= may_be_prime && is_prime; i++) if (may_be_prime % prime[i] == 0) /* NO */ is_prime = NO; /* exit */ if (is_prime) /* if it IS a prime... */ prime[count++] = may_be_prime; /* save it */ } printf("\nPrime Number Generation Program"); printf("\n===============================\n"); printf("\nFirst %d Prime Numbers are :\n", count); for (i = 0; i < count; i++) { if (i % 10 == 0) printf("\n"); printf("%5d", prime[i]); } return 0;}
解法2:篩選法用一個數組x[]儲存3,5,7...這些奇數,則x[i]存的就是2i+3,這樣初始設定所有數都沒有篩掉,然後逐次把合數篩掉。實際就是把2i+3的倍數篩掉,2i+3的倍數可以寫成(2i+3)j,j>1,不然j=1會篩掉自己。又由於偶數不用考慮,所以篩掉的數應該為(2n+1)(2i+3)=2[n(2i+3)+i]+3。因此要篩掉的數在數組中的位置為n(2i+3)+i,n=1,2,3...n=1時,這個值就是2i+3+i,n=2時為2(2i+3)+i;如果一共有N個元素,則x[]中最後一個元素x[N-1]=2N+3,由此就可以得到2到2N+3之間所有素數。代碼如下,注意下面的代碼並不是求前200個素數,而是求的從2到403之間的素數。
/* ------------------------------------------------------ *//* FUNCTION sieve : *//* This program uses Eratosthenes Sieve method to *//* generate all primes between 2 and MAXSIZE*2+3. This *//* is a very simple yet elegant method to generate primes *//* *//* Copyright Ching-Kuang Shene July/01/1989 *//* ------------------------------------------------------ */#include <stdio.h>#define MAXSIZE 200#define DELETED 1#define KEPT 0void main(void){ int sieve[MAXSIZE+1]; /* the sieve array */ int count = 1; /* no. of primes counter */ int prime; /* a generated prime */ int i, k; /* working variable */ printf("\nEratosthenes Sieve Method"); printf("\n========================="); printf("\n\nPrime Numbers between 2 and %d\n", MAXSIZE*2+3); for (i = 0; i <= MAXSIZE; i++) /* set all items to be*/ sieve[i] = KEPT; /* kept in the sieve */ for (i = 0; i <= MAXSIZE; i++) /* for each i, it */ if (sieve[i] == KEPT) { /* corresponds to 2i+3*/ prime = i + i + 3; /* if it is not sieved*/ count++; /* prime=2i+3. */ for (k = prime + i; k <= MAXSIZE; k += prime) sieve[k] = DELETED; /* screen multiple*/ } printf("\n%6d", 2); /* output part. */ for (i = 0, k = 2; i <= MAXSIZE; i++) if (sieve[i] == KEPT) { if (k > 10) { printf("\n"); k = 1; } printf("%6d", 2*i+3); k++; } printf("\n\nThere are %d primes in total.", count);}