练车加端盘子也挡不住我学习系列——埃氏(Eratosthenes)筛法

素数表的获取

普通算法

依次枚举每个数,判断它是否为素数即可!此类算法较低效,复习度O(n)较大,并不实用。(以1到100为例)

//普通类算法
#include<iostream>
using namespace std;
int main()
{
    bool flag=true;//是素数
    for(int i=2;i<100;i++)
    {
        for(int j=2;j<i;j++)
        {
            if(i%j==0)
            {
                flag=false;//不是素数
                break;
            }
        }
            if(flag) cout<<i<<" ";
            flag=true;//重置
    }
            return 0;

}

改进算法

我们知道一个数n可以分解为两个数的乘积,一个是小于或等于sqrt(n)的数,另一个是大于或等于sqrt(n)的数。所以我们可以在sqrt(n)范围内即可判断其是否为素数,算法复杂度为O(sqrt(n))。(1到100为例)

//改进算法
#include<iostream>
#include<math.h>
using namespace std;
#define Max 100
int prime[Max],counts=0;//储存素数和计数器
bool p[Max]={0};//记录是否为素数
bool IsPrime(int n)
{
    if(n==1) return false;
    int sqr=(int)sqrt(1.0*n);
    for(int i=2;i<=sqr;i++)
        if(n%i==0) return false;
    return true;
}
void FindPrime()
{
    for(int i=1;i<100;i++)
        if(IsPrime(i))
    {
        prime[counts++]=i;
        p[i]=true;
    }
}
int main()
{
    FindPrime();
    for(int i=0;i<counts;i++)
        cout<<prime[i]<<" ";
}

埃氏筛法算法(实用)

枚举每一个数字,然后以第一个素数为准,开始去除其倍数的数,以此类推。直到去除完后,最后没有被筛选掉的即为我们所需的素数,其复杂度为O(nloglogn)。

//埃氏筛选算法
#include<iostream>
using namespace std;
#define Max 100
int prime[Max],counts=0;
bool p[Max]={0};
void FindPrime()
{
    for(int i=2;i<100;i++)
    {
          if(p[i]==false)
          {
              prime[counts++]=i;
      for(int j=i+i;j<100;j+=i) p[j]=true;
          }
    }
}
int main()
{
    FindPrime();
    for(int i=0;i<counts;i++) cout<<prime[i]<<" ";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/pipihan21/article/details/107584038