筛选法求素数

n素数的定义: n 不能够被[2,sqrt(n)?]中任意一个整数整除,则n是素数。
n用此方法找出不大于n的所有素数效率太低,下面介绍一个求素数的经典算法
——筛选法求素数

(1)准备:开辟一个长度是10000的数组isPrime初始化为1

这里写图片描述

(2)筛选:i从2到100,做:若i是素数,划去i的倍数,即isPrime[2*i]、 isPrime[3*i]…..置为0

(3)输出:i从2到10000,做: 若isPrime[i]==1, 则i是素数,输出

思考:为何筛选一步循环是i从2到100而不是i从2到10000?
减少循环次数,增加运算速度


#include<stdio.h>
#include<math.h>
#define N 10000
int isPrime[N+1];
void initPrime()
{
 int  i, k, m;
 for(i=1;i<=N;i++) isPrime[i]=1; /*初始化*/
         m=(int)sqrt(N);
 for(i=2;i<=m;i++) /*筛选过程*/
 {
       if(isPrime[i]==1)
      for(k=i+i;k<=N; k=k+i)//寻找i的整数倍  化为零
    isPrime[k]=0;
 }
}
int main()
{
 int  i;
     initPrime();
 for(i=1;i<=N;i++) /*输出10000以内的所有素数*/
    {          
         if(isPrime[i]==1)
   printf("%5d",i);   //这里输出的i而不是isPrime[i]
     }
 return 0;
}


/*
      如果需要需要将所有素数存入一个数组以备其他函数使用,可用如下程序实现
*/

#include<stdio.h>
#include<math.h>
#define N 10000
/*求N以内的素数,形参数组prm存储所有素数,素数个数由函数返回*/
int prime (int prm[]) 
{
int i, prmNum, n;
    int isPrime[N+1]; /*标志数组*/
    for(i=0; i<=N; i++) /*将isPrime数组元素初始化为1*/
           isPrime[i]=1;
    n = (int)sqrt(N);
for(i=2; i<=n; i++)
{
 if(isPrime[i]) /*如果i是素数*/
   {
         for(int j=2*i; j<=N; j=j+i) /*筛选掉是素数的整数倍*/
         isPrime[j]=0;//不是isPrime[i] = 0
    }
}
for(prmNum=0,i=2;i<=N;i++)  /*扫描IsPrime数组*/
{
    if(isPrime[i]==1) /*如果i是素数,存入素数数组prm*/
         prm[prmNum++]= i ;
}
return prmNum; /*返回素数个数*/
}
int main()
{
  int i, prmNum,  prm[N];
  prmNum=prime(prm); /*调用筛选素数函数, prmNum为素数个数*/
  for (i=0;i<prmNum;i++) /*输出10000以内的所有素数*/
  {
     printf("%5d",prm[i]);
     if(prmNum%10==0) /*每行打印10个素数*/
           printf("\n");
  }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值