for 循环的简单应用
一:寻找素数
素数是仅能被1和它自身整除的数。例如:“2”能被1和2整除,所以2是素数;“6”除了能被1和6整除之外,还能被2,3整除,所以6不是素数。
素数的求解方法可以采用试除法,即依次用数字除以或者被除,通过运算结果结果来以判断是否满足条件。故只需要将该数与小于它的数字相除就能判断是否为素数,因此用到for循环;
#include <stdio.h>//输出100~200之间的素数
int main()
{
int num = 0;
int count = 0; //对素数的个数进行计数
for (num = 100; num<= 200; num++) //对100 ~200的每个数进行判断
{
int i = 0;
for (i = 2; i < num; i++)
{
if (num%i == 0) //若取余为零,说明不是素数,跳出对该数判断的循环。
break;
}
if (i == num) //要判断的数已经和小于自身的数(不包括1和它本身)全部比较了,均不满足以上条件,说明该数是素数。
{
printf("%d ", num);
count++;
}
}
printf("\n一共有%d个素数",count);
return 0;
}
运行结果:
以上代码便能完成素数的输出,但是仍有些许地方可以进行优化,使得代码更加高效。下面分析:
1. 偶数(不包括2)必定不是素数,因为,偶数都能被2整除。
故判断的区间可以改成100~200之间的所有奇数,即for (num = 101; num<= 200; num+=2);
2. 关于判断一个具体的数(比如104)是否是素数,不用试除到103。因为任何一个数都可以写成两个数的乘积的形式,由于我们是从2开始试除的,所以2是试除的第一个判断条件。若被2整除,以104为例,即104/2=52.....0,可知52就是试除的极限值,当我们试除的数超过52时,一定是一个小于2的数和试除的数相乘才等于104。
换种说法来讲,2是一个数的次小因数,num/2是这个数的次大因数。所以判断条件可以改为for (i = 2; i < num/2; i++); 相对应的,后面的if语句也要做出调整 if (i == num/2) ;
更近一步来说,num/2也不是最佳的试除极限。num的算术平方根才是最佳试除极限,可以想象成A的算术平方根为a,但是我们给这两个a分别记做a1,a2。 a1在前,a2在后,并且从2依次试除到a1; A=a1*a2,已经完成了对数字A的因数拆分,试除时 从2到a1再到 大于a1的数,其意义等同于,增大了a1值,减小了a2值。(一个值增大a1,另一个值减小a2;而增大后的值a1 就是 原来的a2值);所以判断语句改为 for (i = 2; i <=sqrt(num); i++); if语句改为 if (i >sqrt(num) ) ;
综上所述,
优化后的代码为:
#include <stdio.h>//输出100~200之间的素数
#include <math.h>
int main()
{
int num = 0;
int count = 0; //对素数的个数进行计数
for (num = 101; num<= 200; num+=2) //对100 ~200中的奇数进行判断。
{
int i = 0;
for (i = 2; i <=sqrt(num); i++) //比较范围是从2到自身的算术平方根的值
{
if (num%i == 0)
break;
}
if (i >sqrt(num) ) //注意判断条件,从2到根号下num 都不能整除,说明该数是素数。
{
printf("%d ", num);
count++;
}
}
printf("\n一共有%d个素数",count);
return 0;
}
二:输出 九九乘法口诀表
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
......
用到两层for循环,第一层是1~9的乘数;第二层是每个乘数和 从1到它自身相乘;
代码为:
#include <stdio.h>//输出99乘法表
int main()
{
int i = 0;
for (i = 1; i <= 9; i++)
{
int j = 0;
for (j = 1; j <= i; j++)
{
printf("%d*%d =%2d ",i,j, i*j); //%2d 输出结果占两个位置,如果输出的是个位数,采取右对齐的方式,百位用空格填补。
}
printf("\n");
}
return 0;
}
运行结果:
三:判断闰年,并输出1000~2000中的闰年
闰年的定义:1.能被400整除的是闰年;
2. 能被4整除并且不能被100整除的是闰年。
代码的核心还是for循环。
代码为:
#include <stdio.h>//输出1000~2000中的闰年;能被400整除的是闰年,能被4整除并且不能被100整除的是闰年。
int main()
{
int year = 0;
int count = 0; //用来记录闰年的数量
for (year = 1000; year<= 2000 ; year++)
{
if (year % 400 == 0) //先判断能否被400整除
{
printf("%d ", year);
count++;
}
else if (year % 4 == 0) //不能被400整除后,在判断能否被4整除且不被100整除
{
if(year %100 !=0)
{
printf("%d ", year);
count++;
}
}
}
printf("\n1000~2000中闰年一共有 %d 个",count);
return 0;
}
运行结果:
以下是编程过程中出现的错误和分析:
当代码内容不变,而位置发生改变时,有了不同的情况:
产生了以下结果:
分析原因: 可以看到,比正确的结果少了3年。分别是1200年,1600年,2000年。仔细对比之后就不难发现,如果先判断400,再判断4,1200等可以正常输出;但是先判断4,在判断400,由于 else if 语句,1200在不满足4的判断条件后,又无法进入400的判断条件中,所以1200不能正常输出。
解决措施:有两种,一是先判断400的条件,再判断4的条件。
二是将else if 语句 更换成 if 语句,使得1200在不满足4的判断语句的情况下,也能进入400的判断条件中。
此时,输出结果正确。可见细节很重要,很重要,很重要。
优化代码: 严格来讲,以下这个代码并没有减少时间复杂度和空间复杂度,主要是运用逻辑运算符让代码的篇幅减小,看起来更加整齐。
#include <stdio.h>
int main()
{
int year = 0;
int count = 0;
for (year = 1000; year <= 2000; year++)
{
if (year % 4 == 0 && year % 100 != 0 )
{
printf("%d ", year);
count++;
}
if (year % 400 == 0)
{
printf("%d ", year);
count++;
}
}
printf("\n%d", count);
return 0;
}
菜鸟上路,若有不当之处,望教正~