这几天给学生上完循环结构后,想给学生出一道这样的题,题目如下:
**用所学的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之间就可以了
这个小小的改动就让计算量缩小了一般,可见好的算法很重要。