素数线性筛选

素数线性筛选

素数的定义是除了1和自身能被整除外,没有其他数能被它整除。除此之外,1既不是素数,也不是合数。因此, 素数是从2开始的。

思想

素数线性筛选是指根据素数的定义,合数为若干个素数的乘积。因此,可以利用已经确定的素数的K倍来筛掉不是素数的数。

时间复杂度

设筛选区间为 [1, n] 的所有素数。则由算法的特性可知,对于每个素数 p_i ,均要筛掉 \lfloor\frac{n}{p_i}\rfloor-1 个合数, 每个合数为 2p_i,3p_i,4p_i, ..., kp_i, kp_i<=n.

则总的时间复杂度为

T(n) = \sum_{p_i=2}^{n}{\frac{n}{p_i}}=nln(lnn),p_i\ is\ prime.

由于 ln(ln1000,0000) \approx 2.9134 (一亿规模), 故该算法又称为线性筛素数。

优化后的代码部分:

// 重定义类型
using array_int = vector<int>;
using array_int_ref = array_int &;
using array_bool = vector<bool>;
using array_bool_ref = array_bool &;

/***
朴素素数线性筛选算法
**/
void regular_sieve(array_int_ref array, const int size) {
    // 使用sqrt(size)大小的素数来进行筛选,进行优化
    const int sqrt_size = sqrt(size) + 1;

    // 使用标记数组进行标记是否为素数
    array_bool is_prime(size+1, true);
    for (int i = 2; i <= sqrt_size; ++i) {
        if (is_prime[i]) {

            // 使用i*i,进行优化
            for (int j = i * i; j <= size; j += i) {
                is_prime[j] = false;
            }
        }
    }

    // 清空无效数据
    array.clear();

    // 将标记为素数的数收集起来
    for (int i = 2; i <= size; ++i) {
        if (is_prime[i]) {
            array.push_back(i);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 区间素数线性筛选 假设应用场景为求一个区间长度远小于右端点的所有素数,该区间为 。如若使用朴素素数线性筛选,则需...
    你今天作业做了吗阅读 2,187评论 0 1
  • 春分,古人讲:过了今日燕子就要从南方飞来了。这个时节莺飞草长、春暖花开、万物复苏、到处都是生机盎然的景象。...
    花姐夏菲菲阅读 1,826评论 0 0
  • 亲爱的姑娘: 已经很多次在脑海里构想你了,YY你的样子,你的可爱,我甚至可以确定,你会出现在某个未来。 ...
    是许青山阅读 3,395评论 4 14
  • 小张、小刘是年纪相仿的两个年轻人,他们都来自经济状况一般的三线城市农村,家庭背景相似却不相同,都没有父母的帮助,都...
    不思斋主人阅读 3,122评论 0 1
  • 小的时候,特别喜欢唐诗,因为其朗朗上口,意境丰富。尤其是李白,喜欢他的飘逸、豁达,读着他的诗,感觉自己都飘起来了,...
    十八贝勒阅读 1,332评论 0 0