经典算法——筛选法求素数(素数筛选)

[数值问题]素数筛选

内存限制:128 MB时间限制:1.000 S

题目描述

输入一正整数n(2<=n<=5*10^6),按顺序输出2到n范围内的所有素数。

输入

输入共一行一个数,表示n的值。

输出

输出若干行,每行5个素数,用空格隔开。

样例输入

20

样例输出

2 3 5 7 11
13 17 19

素数在很多应用领域有很重要的用途,寻找一个高效的算法十分重要。例如,找出10000以内的素数可能仅仅是为某个程序做的准备工作,为提高程序的效率,希望在尽可能短的时间内完成。下面介绍一个经典算法——筛选法求素数。

主要思想是以空间换时间,是很常用的一种提高算法效率的方法。这是一种思想,不是一种算法。这种思想的主要应用有以下两种:
第一种是将之前计算的结果保存起来,方便当前计算之用,从而降低计算量。这种思想的典型体现就是动态规划算法,从求解规模较小的子问题开始,逐步递推求解规模更大的子问题,每次计算都将得到的最优结果保存起来,在后面的计算中,利用前面的计算结果求得当前的最优值,然后再保存起来,如此递推下去。

所谓筛选法是指从小到大筛去一个已知素数的所有倍数。以筛选法求10000以内的素数为例,根据素数2可筛去4、6、8、…、9998、10000等数,然后根据索数3可筛去9.6.
12.15,…,9999等数,由于4已被筛去了,下一个用于筛选的素数是5…依此类推,最后剩余的就是10000以内的素数。

具体实现代码如下:

#include<stdio.h>
#define N 5000000//根据题意开一个数组
#include<math.h>
int a[N+1];//全局变量数组
void prime(int n)
{
	int m=0,i,j;
	for(i=0;i<n;i++)
	a[i]=1;//给所有数赋值为1
	a[0]=a[1]=0;//0和1不是素数
	m=(int)sqrt(n);
	for(i=2;i<=m;i++)//从二开始依次筛选2,3....的倍数
	{
		if(a[i]==1)//筛选过的就不需要进入循环了,如2的倍数有4,4已经被筛选了即a[4]==0不进入循环
		{
			for(j=2*i;j<n;j=j+i)
			{
				a[j]=0;//将不是素数的数赋值为0
			}
		}
	}
 } 
int main(void)
{
	int n,i,b=0;
	scanf("%d",&n);
	prime(n);//使用函数筛选
	for(i=1;i<=n;i++)
	{
		if(a[i]==1)//输出筛选后剩余的素数
		{
			printf("%d ",i);
			b++;
			if(b==5)//五个数一行
			{
				printf("\n");
				b=0;//用完初始化
			}
		}
	}
	return 0;
 } 
  • 13
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捉只树袋熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值