码迷,mamicode.com
首页 > 其他好文 > 详细

求素数(从判断素数到筛法)

时间:2020-06-04 19:40:06      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:没有   alt   sqrt   枚举   false   出现   ++   ==   就是   

判断素数

  • 最简单的判断就是根据素数的定义:只有两个因子1和本身(1不是素数)。时间复杂度O(n)
bool is_prime(int x){
    if(x == 1) return false;
    rep(i , 2 , n-1){
        if(x % i == 0){
            return false;
        }
    }
    return true;
}
  • 我们知道因子都是成对出现的,所以在枚举时,可以只枚举2-\(\sqrt x\) .时间复杂度O(\(\sqrt n\))
bool is_prime(int x){
    if(x == 1) return false;
    rep(i , 2 , sqrt(x)){
        if(x % i == 0){
            return false;
        }
    }
    return true;
}
  • 数学上有个定理,只有形如6n-1,6n+1的自然数才可能是素数。简要说明一下:所有自然数都可以写成6n,6n+1,
    6n+2,6n+3,6n+4,6n+5.可以简单的根据偶数一定不是素数排除6n,6n+2,6n+4.而6n+3可以写成3(2n+1)是大于3的倍数也一定素数。所以可以进一步优化。
bool is_prime(int x){
    if(x == 2 || x == 3) return true;
    if(x == 1 || (x%6!=1 &&x%6!=5)) return false;
    rep(i , 2 , sqrt(x)){
        if(x % i == 0){
            return false;
        }
    }
    return true;
}

埃氏筛法和欧拉筛法

  • 埃氏筛法思路是:用已经筛选出来的素数去过滤所有能被它整除的数,即满足p|x的自然数x。我们知道2是最小的素数,通过2筛去所有2的倍数。然后往后
    3没有被筛,所以3是素数,通过3筛去所有3的倍数,以此类推。时间复杂度(\(nlog(log(n))\)
    技术图片
void Erasieve(int n){//筛选1-n间的素数
    rep(i , 1 , n) is_prime[i] = true ;//初始都为素数
    is_prime[1] = false; is_prime[2] = true ;
    rep(i , 2 , n){
        if(is_prime[i]){//判断是否为素数
            //prime[++len] = i ;//加入素数表
            for(int j = 2*i ; j <= n ; j+=i){//通过该素数筛去素数倍数
                is_prime[j] = 0;
            }
        }
    }
}
  • 欧拉筛法:

求素数(从判断素数到筛法)

标签:没有   alt   sqrt   枚举   false   出现   ++   ==   就是   

原文地址:https://www.cnblogs.com/nonames/p/13045388.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!