[C語言]經典且基本的問題之素數
阿新 • • 發佈:2018-12-11
簡介
本文將介紹關於c語言中一個非常簡單且非常經典的問題,求100~200之間的素數,以及對程式碼的優化。
正文
求解素數問題最主要的就是先要了解什麼是素數? 質數(prime number)又稱素數,有無限個。質數定義為在大於1的自然數中,除了1和它本身以外不再有其他因數。也就是說除了1和它本身不能再被別的數整除。 附上程式碼如下:
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
printf("100~200之間的素數為:\n");
for(i=100; i<=200; i++)//判斷i是否為素數
{
for(j= 2; j<i; j++)//j為除數,取值2到被除數的前一個數
{
if(i%j == 0)//如果在這個範圍內能被整除的話說明i不是素數,則跳出迴圈進行下一個數的判斷
{
break;
}
}
if(j == i)//此時被除數等於除數,所以這個數字i就是素數
{
printf("%d ",i);
}
}
return 0;
}
這種就是最經典的求解素數的辦法。那麼相對於這種辦法我們還能想到優化這個程式碼的方法,那就是改變除數的範圍。 附上程式碼如下:
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
printf("100~200之間的素數為:\n");
for(i=100; i<=200; i++)
{
for(j=2; j<(i/2); j++)//將除數的範圍改為2到被除數的一半之前
{
if(i%j == 0)
{
break;
}
}
if(j >= (i/2))
{
printf("%d ",i);
}
}
return 0;
}
這次的優化是將除數的範圍縮小到大於等於2,小於被除數的一半,這是為什麼呢? 因為如果一個數字i可以寫成i=a*b的形式,那麼a或者b的值絕對小於(i/2)。所以此處只需要除到被除數的一半即可,前半部分都沒有可以被整除的數,後半部分也絕對不可能會出現。那麼程式碼的運算次數也減少了一半。 還有一種優化方式程式碼如下:
#include<stdio.h>
#include<math.h>
int main()
{
int i = 0;
int j = 0;
printf("100~200之間的素數為:\n");
for(i=101; i<=200; i+=2)//偶數不可能是素數
{
for(j=2; j<=sqrt(i); j++)//將除數的範圍改為2到被除數的開平方之前
{
if(i%j == 0)
{
break;
}
}
if(j > sqrt(i))
{
printf("%d ",i);
}
}
return 0;
}
這一次相對於上面兩種有了更大的優化,優化了兩處: 第一處是將除數的範圍改變到被除數的開平方處,這還是用到上面的定理,如果一個數字i可以寫成i=a*b的形式,那麼a或者b至少有一個數是小於等於開平方i的。那麼在開平方i前都沒有找到可以被整除的數那麼在開平方i之後也絕對沒有。相對於上一種取(i/2)的程式碼運算次數更少。但是在此處要注意要使用sqrt()的函式必須得先呼叫相應的標頭檔案#include<math.h> 第二處優化在於外層迴圈,因為偶數絕對不可能是素數,所以可以直接在外層迴圈中排除偶數,只迴圈奇數就可以了,也減少了運算次數。
總結
本文講述了關於素數的求解以及相對應的優化問題,對於初學者來說應該能提供一些幫助。
PS:大家有什麼更好的方法可以隨時提出來,也歡迎大家批評指正