這屬於算法上的問題,好好考慮一下算法,還要考慮一下素數的定義。
素數是只有1和本身能整除的整數。所以在求素數的時候,要將素數與1到素數本身中間的所有整數都相除,看是否有整除的數,如果有,那肯定不是素數了。但是從算法上考慮,為了減少重復量,開平方后面的數就不用相除了,因為a/b(平方數)=c(小一點的數),同樣a/c=b。舉例說明:
25,開平方以后是5,那么整除2~5就可以了,如果有滿足條件的,就是素數。
這樣做可以減少循環次數,素數是因子為1和本身, 如果數c不是素數,則還有其他因子,其中的因子,假如為a,b.其中必有一個大於sqrt(c) ,一個小於sqrt(c) 。所以m必有一個小於或等於其平方根的因數,那么驗證素數時就只需要驗證到其平方根就可以了。即一個合數一定含有小於它平方根的質因子。
再比如:24的因數有1、2、3、4、6、8、12、24
按定義應該用2-23去除,但經過分析上面的數可以發現
1×24、2×12、3×8、4×6
如果2、3、4是某個數的因數,那么另外幾個數也是,反之也一樣
所以為提高效率,可以只檢查小於該數平方根的那些數,如24的平方根大於4小於5,檢查2-4就可以了!
例如:問題:令Pi表示第i個素數。現任給兩個正整數M <= N <= 10000,請輸出PM到PN的所有素數。
我的代碼:
紅色部分為應用sqrt方法快速判斷是否為素數,防止超時:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include<stdbool.h> 4 #include<math.h> 5 6 int main() 7 { 8 int min,max; 9 scanf("%d",&min); 10 scanf("%d",&max); 11 int i=1,sushu[10000],num=3; 12 sushu[0]=2; 13 while(i<max){ 14 bool tag=true; 15 for(int k=2;k<=sqrt(num);k++){ 16 if(num%k==0){ 17 tag=false;//判斷不是素數 18 break; 19 } 20 } 21 if(tag){ 22 sushu[i]=num; 23 i++; 24 } 25 num+=2; 26 } 27 28 int m=0; 29 for(int k=min-1;k<max;k++){ 30 m++; 31 if(k==max-1){ 32 printf("%d",sushu[k]); 33 }else{ 34 if(m%10==0){ 35 printf("%d\n",sushu[k]); 36 }else{ 37 printf("%d ",sushu[k]); 38 } 39 } 40 } 41 return 0; 42 }