前话:作为初学者,多刷初学者应该刷的题是非常重要的,相同的题目也可能有不同的算法,算法的不同决定计算机的运算是否高效,先来学习下用多种解法来解“打印1到100中的素数”题。
题目:按要求打印100到200中的素数。
- 第一种解法:先来最容易理解的第一种思路,在100到200中,只要能有被100到200中整除则该数不是素数,这里则需要用到两个循环,第一个循环来确定被除数,第二个循环来确定除数。我们可以设置flag来判断是否打印素数,flag=1则打印素数,flag=0则跳出第二个循环不打印素数,即判断下一个数是否为素数。代码如下:
#include <stdio.h> int main() { int i = 0; int j = 0; for (i =100; i <= 200; i++) { int flag = 1; for (j = 2; j <= i -1; j++) { if (i % j == 0) { flag = 0; break; } } if (flag == 1) { printf("%d ", i); } } return 0; }
第二种解法:思路:一个数一定可以被拆分为两个数相乘,例如16为4与4相乘或8和2相乘,由此我们可以发现,相乘之间的数字一定至少有一个数是小于或等于根号16,则得出一个结论:我们只需要将除数从2开始加到根号下的被除数即可,这运算效率远小于上一种解法。代码如下:
#include <stdio.h> #include <math.h>; int main() { int i = 0; int j = 0; for (i =100; i <= 200; i++) { int flag = 1; for (j = 2; j <= sqrt(i); j++) { if (i % j == 0) { flag = 0; break; } } if (flag == 1) { printf("%d ", i); } } return 0; }
第三种解法:思路:其实素数不可能是偶数,因为偶数一定能被2整除,因此我们可以从101开始每个数之间加个2避开偶数,那么需要被除的数又会减少了一半,是否对比第一种解法高效很多呢?代码如下:
#include <stdio.h> #include <math.h>; int main() { int i = 0; int j = 0; for (i =101; i <= 200; i+=2) { int flag = 1; for (j = 2; j <= sqrt(i); j++) { if (i % j == 0) { flag = 0; break; } } if (flag == 1) { printf("%d ", i); } } return 0; }
需要注意的是,一开始初始化flag的时候需要将flag=1放在第一个循环里头,因为若上一个数判断该数不是素数flag=0后进行下一个数判断则需要把flag重新赋值为1。
结果为 :