1. 程式人生 > >[C語言]經典且基本的問題之素數

[C語言]經典且基本的問題之素數

簡介

  本文將介紹關於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:大家有什麼更好的方法可以隨時提出來,也歡迎大家批評指正