初学筛法(c语言)

来源:互联网 发布:karlie kloss 编程 编辑:程序博客网 时间:2024/06/05 16:43

对于给定n个数,求其中的素数并输出的问题,相信刚开始我们学习语言的时候,我们一定会理所当然的选择下面的这种方法,为什么呢,因为刚开始我们只学了这一种方法,请看代码

求100以内的素数

#include<stdio.h>
#include<math.h>
int main(void)
{
int j,i;
for(i=2;i<=100;i++)//因为知道0和1不是素数,所以直接从2开始计数
{
if(i==2)//2不能用下面的循环判断,所以在刚开始的大循环中遇到2应首先输出
printf("%d ",i);
else
{
for(j=2;j<=sqrt(i);j++)//用循环判断是不是素数

{

if(i%j==0)

break;//如果if判断值等于0,直接跳出循环,判断下一个i值
 
}
if(j>sqrt(i))//这个语句一定要写在循环的外面,因为此语句是属于大循环里面的
printf("%d ",i);
}
}
return 0;

}

这就是我们刚开始学习c语言的时候学习的,也许到现在很多同学都还在理所当然的在使用的代码,这不是老师或者是书本的错,而是这个代码好理解,对于刚开始学习语言的同学,此代码不至于磨灭同学们的学习语言的兴趣,但是,随着我们了解的深入,我们会发现其实这段代码处理小一点的数,速度还是不错的,但是,当我们遇到大数的时候,比如1000000000,甚至更大的数的时候,再用这个代码,恐怕不是几秒就能算出来的吧?

这时候我们就要用到另一个方法-------筛法

代码如下:

筛法求100以内的素数

#include<stdio.h>
#include<math.h>
int main(void)
{
int a[101];//下标用到100,所以长度定到101
int i,k,d=2;
for(i=2;i<=100;i++)//开始把每个元素都定为0,相当于做记号
a[i]=0;
do{                           //do循环是程序的核心,主要任务是把一些100以内的素数都选出来,比如2.3.5的倍数
k=d;
if(a[k]==0)//刚开始k=2,这两个语句的目的就是不让a[2]=1,而是从4开始
k=k+d;
while(k<=100)//把从开头素数以外的素数的倍数下标的数都变成1,也是做记号
{
a[k]=1;
k=k+d;
}
d=d+1;//2的倍数找完找3的倍数,一直往后找
}while(d<=sqrt(100));
for(int j=2;j<=100;j++)//输出素数
{
if(a[j]==0)
printf("%d ",j);
}
return 0;
}

筛法对于大数的处理相对于上一种方法还是比较快的,它的核心思想其实就是用几个初等的素数,比如2.3.4.5等,找到这些数的倍数,然后筛去它们(通过给它们做标记,让对应下标的元素等于0或1)

比如对于一行数:

  2  3  4  5  6  7  8  9  10  11  12  13  14  15

定义数组a[16],与数对应的数组元素为:

a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10] a[11] a[12] a[13] a[14] a[15]

首先 让每个元素都为0

然后 d=2,k=d,if语句判断符合,k=k+d;

寻找k的倍数 从4开始让2的倍数都等于1

循环完之后数组元素等于0的数是:

  2  3     5     7     9     11      13      15

然后 d=d+1;

把除3外 是3的倍数的对应数的数组元素变为1

剩下为0的元素是:

  2  3     5     7            11      13        

到此你可发现刚开始的一组数,现在只剩下了素数!



0 0
原创粉丝点击