1. 程式人生 > >實現1-1000中所有素數的和

實現1-1000中所有素數的和

這幾天給學生上完迴圈結構後,想給學生出一道這樣的題,題目如下:

**用所學的while,do…while,for迴圈實現1-1000所有素數的和。
要求:獨立完成,可以網上查閱資料,但必須要理解程式的意思。**

根據這個題目,會有很多種編寫方式,方法不唯一,我下面寫幾種方法。
在寫程式碼之前,需要分析一下這道題應該怎麼下手,也就是我們所謂的演算法,一個好的演算法能提高程式的運算效能和執行效率,那麼這道題怎麼考慮呢?
1.要知道素數的定義
素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數!
2.怎樣去實現(以for迴圈為例進行講解)
(1)需要設定變數a作為一個1-1000的數,因為1不是素數,我們直接從2開始,以下面虛擬碼這種形式進行:

for(a=2;a<=1000;a++)
{
   ...
}

(2)既然1-1000的數都有了,那麼我們就要去判斷每一個數是不是素數,這樣我可以用一個巢狀迴圈的形式進行逐個判斷a是否是素數,虛擬碼如下:

for(a=2;a<=1000;a++)
    {
        j=0;   //每一次迴圈都需要將其初始化為0,為了下面正確使用
        for(i=2;i<a;i++)
        {
            if(0 == a%i) //判斷a是否能被i整除,要是能整除j會自加
            {
                j++;
            }
        }
        if
(j==0) //判斷j的值,如果一直是0證明這個a就是一個素數 { sum = sum+a;//進行和操作 } }

這樣我們就能完成素數的和。
下面是我寫的幾種方法。
方法一:
只用for迴圈進行實現,程式碼如下:

#include <stdio.h>

/* 素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數 */

void main()
{   
    int sum=0;
    int a=0;
    int i=0;
    int j = 0;                  // 變數宣告並初始化
for(a=2;a<=1000;a++) // 因為1不是素數,我們直接從2開始 { j=0; // 保證每一次j的值有效,需要初始化 for(i=2;i<a;i++) { if(0 == a%i) // 如果a能被整除j會加1 { j++; } } if(j==0)// 判斷在巢狀的迴圈結束後,如果j還是0表示a就是素數 { sum = sum+a; // 進行素數和操作 } } printf("sum = %d\n",sum); }

這樣我們就把素數的程式碼完成了,我們看一下它的執行結果,如下:
這裡寫圖片描述
方法二:
只用while迴圈實現素數和,程式碼如下:

#include <stdio.h>

/* 素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數 */
void main()
{   
    int sum = 0, a = 2, i=2,j = 0;  // 

    while(a<=1000) //迴圈取出a的值,下面進行判斷a是否為素數
    {
        j = 0;      // 保證j值有效需要初始化
        i = 2;      // 保證i的值每一次都是從2開始進入下面的while迴圈
        while(i<a)
        {
            if(a%i==0) // 如果a能被整除j會加1
            {
                j++;
            }
            i++;
        }
        if(j==0)// 判斷在巢狀的迴圈結束後,如果j還是0表示a就是素數
        {
            sum = sum+a;// 進行素數和操作
        }
        a++;//自加
    }
    printf("sum = %d\n",sum);
}

其實while迴圈的原理是和for迴圈是一樣的。

方法三:
只用do…while迴圈來實現素數和,程式碼如下:

#include <stdio.h>

/* 素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數 */
void main()
{   
    int sum = 2, a = 2, i=2,j = 0;  

    do
    {
        j = 0;
        i = 2;
        do
        {
            if(a%i==0)
            {
                j++;
            }
            i++;
        }while(i<a);
        if(j==0)
        {
            sum = sum+a;
        }
        a++;
    }while(a<=1000);

    printf("sum = %d\n",sum);
}

這裡面需要注意下與while迴圈語句的區別,while語句是先判斷然後才執行迴圈體語句,而do…while則是先執行迴圈體語句再進行條件判斷,這樣我們就需要將第一個素數2先賦給sum,這樣才能保證程式的正確性。

方法四:
while和for迴圈共同使用完成素數和,程式碼如下:

#include <stdio.h>

/* 素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數 */
void main()
{
    int sum = 0, a = 2, i=0,j = 0;  // 

    while(a<=1000)
    {
        j = 0;
        for(i=2;i<a;i++)
        {
            if(a%i == 0)
            {
                j++;
            }
        }
        if(j==0)
        {
            sum = sum+a;
        }
        a++;
    }
    printf("sum = %d\n",sum);


}

其實原來都是一樣的,那麼用do…while和for迴圈搭配呢,依然能夠完成素數和,方法很多種,只要用心去想,就能把程式碼寫出來,因為C語言非常的靈活,需要多多練習,多多思考。

我上面提供了四種方法,它們的演算法是一樣的,但這樣的演算法能不能再優化一下呢,我在上面的程式中可以看到a%i中的i的範圍始終是2-a之間,這個範圍是否真正合理呢,是不是可以將範圍縮小呢?
其實,我們細想想就會發現,i值的範圍只需要在2-a/2就可以了,大於a/2的數,a%i肯定不為零,所以我們只需要考慮2-a/2範圍就可以了,程式碼如下:
方法五:

#include <stdio.h>

/* 素數又叫質數,它是指只能被本身或1整除的數,注意 1 不是素數 */

void main()
{   
    int sum=0;
    int a=0;
    int i=0;
    int j = 0;                  // 變數宣告並初始化
    for(a=2;a<=1000;a++)        // 因為1不是素數,我們直接從2開始
    {
        j=0;                    // 保證每一次j的值有效,需要初始化
        for(i=2;i<=a/2;i++)     // i的範圍只需要在2-a/2之間就可以了
        {
            if(0 == a%i)        // 如果a能被整除j會加1
            {
                j++;
            }
        }
        if(j==0)                // 判斷在巢狀的迴圈結束後,如果j還是0表示a就是素數
        {
            sum = sum+a;        // 進行素數和操作
        }
    }

    printf("sum = %d\n",sum);
}

結果如下:
這裡寫圖片描述
和之前的值完全一致,表示素數和正確。

我們就將方法一的程式碼進行了一下修改,修改的地方為,如下:

for(i=2;i<=a/2;i++)     // i的範圍只需要在2-a/2之間就可以了

這個小小的改動就讓計算量縮小了一般,可見好的演算法很重要。