算法分析:假设对于一个正数a,如果a的约数只有两个,1和它本身,那这样数叫做素数。我们对a在2—a-1之间取余,如果还能找到第三个约数,使得余数为0,那a就不是素数,如果找不到第三个约数,使得余数不为0,那a就是素数。举个例子,如果a=5,我们判断5是不是质数,只要把5分别与2,3,4取余就好了。即在这个区间范围上,如果还能找到一个约数,使得余数为0,那么5就不是质数,否则,它就是质数。
代码如下:
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a=5;if(a%2==0||a%3==0||a%4==0)printf("a不是质数");else printf("a是质数");}
用上述的方法判断10以内的数很简单,但是如果用上述的办法判断1000呢?那不把人心态弄崩了?所以上述方法不具备普适性。那有啥普适性的方法来解决这个问题呢?先不说,先跟着我一步一步,循序渐进的学习。
优化01—先优化上述代码:优化的核心原因是根据开篇的算法分析,判断有没有第三个约数。
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a,count;a=5;if(a%2==0)count++;if(a%3==0)count++;if(a%4==0)count++;if(count==0)printf("质数");elseprintf("合数"); }
在上述代码中,我们增加了一个变量count来记录a有多少个约数。变量count的初始值为0。
当a % 2 == 0成立时,说明2是a的一个约数,此时count的值加1变为1。同理,当a % 3 == 0,a % 4 == 0也成立时,count值也加1变为3。最后我们通过变量count的值,知道了a有几个约数
同时可以判定a是否为正数。如果count到最后的值仍然是0,即之前的三个if条件语句都不成立,即a不能被2,3,4中的任意一个数整除,说明a除了1和本身之外,没有第三个约数了,此时a是质数。反过来,若count到最后的值不是0,说明之前的三个if条件判断语句中,至少有一个,最多有三个成立,此时a除了1和本身之外,仍然有第三个约数存在,a不是质数,是合数。
**优化02—**仍然可以优化上述代码,如下:
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a,count=0,i;a=5;for(i=2;i<=4;i++)//4+1-2来判断次数 { if(a%i==0)count++;}if(count==0)printf("质");elseprintf("合数");
}
比较优化01和优化02,我们用
for(i=2;i<=4;i++)//4+1-2来判断次数 { if(a%i==0)count++;}
来代替了
if(a%2==0)count++;if(a%3==0)count++;if(a%4==0)count++;
因为我们发现,这三个if语句只有变量值不一样,即2,3,4,其余都是一样的。变量值决定了我们的重复操作数,于是我们想到了用循环来解决。此时for隆重登场了!
更深一步思考,当a等于5的时候,只需要判断2,3,4是不是5的第三个约数(即2,3,a-1)。当a的值不确定的时候,我们需要将
for(i=2;i<=4;i++)//4+1-2来判断次数
改为
for(i=2;i<=**a-1**;i++)//4+1-2来判断次数
就可以判断任意正数a是不是质数了。代码如下:
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a,count=0,i;printf("请输入一个正整数:");scanf("%d",&a);for(i=2;i<=a-1;i++)//4+1-2来判断次数 { if(a%i==0)count++;}if(count==0)printf("质");elseprintf("合数");
}
加一条printf();语句打印合数的约数。代码如下:
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a,count=0,i;printf("请输入一个正整数:");scanf("%d",&a);for(i=2;i<=a-1;i++)//4+1-2来判断次数 { if(a%i==0){ count++;printf("约数%d\n",i);} }if(count==0)printf("质");elseprintf("合数");
}
类似的,再加一条语句,输出3~100间所有的素数。代码如下:
#include <stdio.h>
#include <stdlib.h>
main()
{ system("color f4");int a,i,c;for(a=3;a<=100;a++){ for(i=2;i<=a-1;i++)//i++是什么时候加1? { if(a%i==0)break; }if(i==a)//最终的质数与最终的i是相等的。 printf("%d\n",i); }
}
如果你认认真真地读完此文,并认真地上机操作,你就已经具备了判断任何一个正整数是不是质数的“降龙十八掌”了。