首先,我们应当先复习一下原始的筛选法原理,先圈出2,并且划掉列表中2的倍数(即其他偶数),然后回到开始,圈出第一个没有被画掉的数,画掉剩下数表中他的所有倍数。重复这一过程足够多次数,剩下的没有被画掉的就是我们要寻找的素数。并且,不难推出,我们要在所圈到的不小于sqrt(n)的最大整数之前就要停止筛选,这时候就不用再去找接下来的素数,只需要将没有画掉的数字画上即可。这便是原始的筛选法。
其次,对于代码的实现,我们不妨可以对原先筛选法做出一些修改,使其更容易,也更好被人理解地促成代码实现。原始的方法里面是要找到一个素数就要划掉他的所有倍数,明显,这是很难用代码实现的,我们可以这样子做:提前设置一组足够长度的数组,我们用这个数组来储存已经找到的素数,并且,我们利用循环,使得循环一开头数组对应项都能被塞入最新找到的素数,然后及时输出,每轮最后在使得循环变量更新,在中间,我们再放一个循环,用于检测到剩下的数里面第一个能找到的素数,然后马上就赋值给循环变量,这样代码整体就能实现正确的素数输出。额外的,为了减少工作量,前面的找到的素数,我们可以使其含义变为需要用于筛选的最小素数列,并且在循环末端进行判断,如果刚刚好,其实就不用再让数组继续储存新素数了。
代码实现:
#include
#include
int main()
{
int N;scanf("%d",&N);
int m=floor(sqrt(N));
int a[m];
int i=2,j=0;
while(i<=N){
a[j]=i;
printf("%d\n",i);
if(i==N)break;
int k=i+1,ctt=0;
for(k=i+1;k<=N;k++){
int temp=0;ctt=0;
for(temp=0;temp<=j;temp++){
if(k%a[temp]!=0)ctt++;
}
if(ctt==j+1)break;
}
if(ctt!=j+1)break;
i=k;
if(m>=k)j++;
}
return 0;
}
优化过的形式:
谢谢阅
#include<stdio.h>
#include<math.h>
int main()
{
int N;scanf("%d",&N);
int m=floor(sqrt(N));
int a[m];
int i=2,j=0;
while(i<=N){
static int sign=0;
if(sign==0)a[j]=i;
printf("%d\n",i);
if(i==N)break;
int k=i+1,ctt=0;
for(k=i+1;k<=N;k++){
int temp=0;ctt=0;
for(temp=0;temp<=j;temp++){
if(k%a[temp]!=0)ctt++;
}
if(ctt==j+1)break;
}
if(ctt!=j+1)break;
i=k;
if(m>=i) j++;
else sign=1;
}
return 0;
}
谢谢阅读!
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复