實現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之間就可以了
這個小小的改動就讓計算量縮小了一般,可見好的演算法很重要。