問題描述:在做篩法求質數的問題時,在刪除非質數的數據時,有很多是重複刪除的。例如,如果有一個數是3x7x17x23,那麼在刪除3的倍數時會刪除它,刪除7,17與23的倍數時也都會刪除它。請寫一個程序,在刪除非質數時"絕對"不做重複的工作。
思路:有一個因式分解定理:任何一個合數都可以分解成若干個質數相乘的形式。那麼,num一定可以分解成p的i次方乘以q的形式(p,q是質數且p<q)。所以,需要去除的數就變成了p的2次方,p的3次方,p的4次方......以及p的i次方乘以q,i=1,2,3.......p和q的取值是從小到大的沒有被去除的數,所以很容易就可以寫出如下的程序。
1 #include <stdio.h> 2 #define MAX 1000 3 #define null1 0 4 #define NEXT(x) x=next[x] 5 #define REMOVE(x) { previous[next[x]]=previous[x]; \ 6 next[previous[x]]=next[x]; \ 7 } 8 9 #define INITIAL(n) { unsigned long i; \ 10 for(i=2;i<=n;i++) \ 11 previous[i]=i-1,next[i]=i+1; \ 12 previous[2]=next[n]=null1; \ 13 } 14 15 int main() 16 { 17 unsigned long previous[MAX+1]={0}; 18 unsigned long next[MAX+1]={0}; 19 unsigned long prime,fact,i,mult; 20 unsigned long n; 21 unsigned long count=0; 22 23 scanf("%lu",&n); 24 25 INITIAL(n); //initial the array 26 27 for(prime=2;prime*prime<=n;NEXT(prime)) 28 { 29 for(fact=prime;prime*fact<=n;NEXT(fact)) 30 { 31 for(mult=prime*fact;mult<=n;mult*=prime) 32 REMOVE(mult); 33 } 34 } 35 for(i=2;i!=null1;NEXT(i)) 36 printf("%lu ",i),count++; 37 printf("\nThe sum of the prime numbers is %lu\n",count); 38 }
參考資料:《C語言名題精選百則技巧篇》