欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线性筛选法求素数

程序员文章站 2024-03-21 15:11:04
...

普通求法:

#include<stdio.h>
int main()
{
    int i, n;
    while (scanf("%d", &n) == 1)
    {
         for (i = 2;i <
n;i++)
             if (n % i == 0)
                  break;
         if (i == n)
             printf("Yes\n");
         else
             printf("No\n");
    }
    return 0;
}

这个缺点就是如果n稍微大点运行的时间就很大

在普通的基础上改进方法(sqrt(n)):

#include<stdio.h>
#include<math.h>
int main()
{
    int i, n, x;
    while (scanf("%d", &n) == 1)
    {
         x= (int)sqrt(n);
         for (i = 2;i <=x;i++)
             if (n % i == 0)
                  break;
         if (i > x)
             printf("Yes\n");
         else
             printf("NO\n");
    }
    return 0;
}

用的sqrt,效率提高了,但是还是不够理想

于是我们有线性筛法(欧拉筛法):

原理:素数的倍数一定不是素数。

我们可以用一个长度为n+1的数组来存储信息(这种用另一个数组来保存信息的方法很常见也很有用),首先将所有的数字全初始化为0(素数),再将数字1与第一个素数2标记为1(非素数)从素数2开始将所有小于n的2的倍数都标记为1;继续该过程,将素数3的倍数筛掉,到循环结束时,标记仍为0的数就是素数。

//primer用来保存得到的素数

memset(check , 0 , sizeof(check) );

check[1] = 1;

int sum = 0,i,j;

for(i = 2;i <= n; i++)

{

       if(!check[i])

              primer[sum++]
= i;

       for(j
= i+1;j <= n;j += i)

              check[i]
= 1;

}

线性筛选法求素数

仔细分析这个算法的优化已经很好了,但是有些数字被重复使用了

于是乎真正的欧拉筛选来了

欧拉筛选保证一个合数只会被他最小的质数因子筛序一次

代码如下



check[1] = 1;
int sum =0, i, j;
for (i =
2;i <= n;i++)
{
    if (!check[i])
         primer[sum++]= i;
    for (j = 0;j <sum;j++)
    {
         if (i * primer[j] >n)
             break;
         check[i* primer[j]] = 1;
         if (i % primer[j] ==0)
             break;
    }
}

线性筛选法求素数
线性筛选法求素数
思路:

1.用线性筛法求出N范围内的素数保存在primer中(友情提示:大数组最好放在main函数之外定义,其他的题最好也是这样。为什么?百度“栈帧”,你就知道)
2.对这M组数据,用二分查找对比primer。



#include <stdio.h>

int n,w, primer[1000010],tot,s,i;

int check[100000010];

int main()

{

   
scanf("%d%d",&n,&w);

   
for(i = 2; i <= n; i++)

    {

       
if(check[i] == 0) primer[++tot] = i;

       
for(int j = 1; (j <= tot) && (i*primer[j] <= n); j++)

       
{

           
check[i * primer[j]] = 1;

           
if(i % primer[j] == 0) break;

       
}

    }

   
while(w--)

    {

       
scanf("%d",&s);

       
i = 1;

       
int j = tot, mid;

       
while(i <= j)

       
{

           
mid = (i + j) / 2;

           
if(s == primer[mid])

           
{

                printf("Yes\n");

                break;

           
}

           
else if(s < primer[mid]) j = mid - 1;

           
else i = mid + 1;

       
}

       
if(s != primer[mid]) printf("No\n");

    }

   
return 0;

}

参考资料