sdut-欧拉筛法(线性筛法)---图灵

 这是一道求质数的题目

给定一个正整数 n,请你求出 1∼n 中质数的个数。

输入格式
共一行,包含整数 n。

输出格式
共一行,包含一个整数,表示 1∼n 中质数的个数。

数据范围
1≤n≤106

样例

输入样例:
8
输出样例:
4

前言

求质数的方法诸多但是优化方法小编推荐埃氏筛法和欧拉筛法,两者有利有弊处,如下:

我们可以对比一下欧拉筛(线性筛法)和埃氏筛法,对于埃氏筛法他的时间复杂度是趋近于O(n)级别的,他所使用的空间是比较小的(因为开的数组的个数要少于线性筛法)相比于欧拉筛是要好理解的当然我会说明我对于线性筛法的理解,下面看一下欧拉筛法,他的复杂度是绝对O(n)的,可以举例(6的因数有2和3对于线性筛我们只要看一遍,而对于埃氏筛法我们要看两遍);我将在代码中给出欧拉筛的解析


(示例):

#include<bits/stdc++.h>

using namespace std;
const int N=1e6+10;

int cnt,p[N];//cnt 的值是用来进行记录的,记录p函数中所记录的质数的个数
p[]数组中记录的是素数都有那些个,p和cnt可以说相互不分离在记录的时候
bool st[N];//开st[]数组是记录当前的数字是不是质数,默认的初始值是false
void get_prime(int n)
{
    for(int i=2;i<=n;i++)//从2开始一直扫到第n个
    {
        if(!st[i])p[cnt++]=i;   //第一个数字是2,显然是质数,我们可以把他存在p数组当中
        for(int j=0;p[j]<=n/i;j++)//我们开始遍历这里我们要看到1.遍历的是下标;
        2.p[j]是判断素数的大小,当然为什么是n/i呢???这和我们后面的代码有关
        后面我们会记录st[p[j]*i]=true,这里已经说明p[j]*i相当于一个大于i的值
        我们所要求的数字是比n小的数字,i会遍历到n
        那么我们记录的st的范围会大于n,n后面的就没必要做过多的处理
        当然也是避免数字的越位;
        {
            st[p[j]*i]=true;
            if(i%p[j]==0)break;//那么就有人说了我们为什么还要进行这一步呢,
            两个原因1.j无线加会变成p[j]=0,那么问题就出现了开始的for循环
            不就停止条件变成了0<n/i了吗?我认为这里有把0排除的原因。
            2.进行范围的限定,如果i是p[j]的倍数才会i%p[j]==0
            那么当p[j]是i的因子的时候停止就会避免了 把合数重复赋值
        }
    }
 cout<<cnt<<endl;
}

int main()
{
 int n;
 cin>>n;
 get_prime(n);
}

​

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值