为一个不太懂编程的菜姬师姐解释如何判断素数。
题目:计算大于10000查起的第五个素数(原话,语句有歧义吧)
代码:
#include<stdio.h> #include<math.h> int flag(int x) ///自定义判断一个数是不是素数的函数 { if(x==0||x==1) return 0;///如果不是素数返回0 int q=sqrt(x); int i; for(i=2;i<=q;i++) { if(x%i==0) return 0; } return 1; ///走完前面的语句都没有找到除1之外的因子数 } int main() { int j,cnt=0; ///j作为for循环的数,cnt计数 for(j=10000;;j++) ///语句2省略,无限循环,但有break作为终止条件 { if(flag(j)) ///在if语句里调用判断函数,如果为真,计数+1 { cnt++; } if(cnt==5) ///找到第五个素数,打印输出后跳出循环 { printf("%d ",j); break; } } return 0; }
菜姬师姐表示不知道为什么要对x开根号?int q=sqrt(x);取整;
判断素数就是判断有没有可以被本身整除的因子,如果有,那两个因子要么是一大一小,要么是两个相同的数。以q为中点,小*大 和 大*小是同样的因子。
举例100,2*50,4*25,10*10,25*4,50*2;当i=2的时候,i可以被x整除,直接返回0;不是素数没有太大影响。但素数就会有很大差别。
举例97,97是素数,q=9;如果不开根号,那i会一直加到96,运算了96次。开根号后就只运算了9次。
假设97是合数的话,则97=小*大,在“小”的数里面都找不到因子,在“大”的数里面会找到因子吗?显然找不到。开根号就是对算法的优化,使原来96次的运算变为9次。如果判断的数是1000001,那就少运算了999000次。
其次就是取整问题,for语句2里需要取等号,如果判断的数是9,则p=3,当i=3的时候会return 0;如果判断的数是11,p取整也等于3,当i=3的时候还是不能被11整除,自然不会return 0;慢慢走完循环出来的时候return 1,表示11是素数。