文章目录

  • 素数筛 Prime sieve
    • 一、素数的判定
    • 二、埃氏筛法
    • 三、欧拉筛法
    • 四、六倍原理

素数筛 Prime sieve

素数又称质数:一个大于 1 的自然数,除了 1 和它自身外,不能被其他自然数整除的数叫做素数;否则称为合数(规定 1 既不是质数也不是合数)。

素数筛方法主要有三种:

素数的判定(素数筛)
普通线性筛(埃氏筛法 / 埃拉托斯特尼(Eratosthenes)筛法)
优化后的线性筛(欧拉筛法 / 欧拉函数(Euler)筛)

寻找素数,二重循环暴力查找,复杂度O(n^2),通过循环中只判断到根号 n 可以优化一些。
在数论中,埃氏筛法,O(n loglogn) 的算法,而数据范围达到 1e7 时也不理想,欧拉筛法,O(n) 的线性筛法。

一、素数的判定

暴力枚举,枚举 2 ~ √n 所有数,用 n 去试着除以,若有能整除的 n 为合数,若都不能整除,n 就是质数。
时间复杂度:O(√n)

boolean isPrime(int x){  if(x < 2) return false; // 0 和 1 既不是质数也不是合数 for(int i = 2; i * i <= x; i++)if(x % i == 0) return false;return true;
}

二、埃氏筛法

埃拉托斯特尼: 古希腊数学家、地理学家、历史学家、诗人、天文学家,主要贡献设计出经纬度系统,计算出地球的直径。
埃拉托斯特尼筛法,简称埃氏筛法,寻找质数的方法。

原理:要得到自然数 n 以内的全部素数,必须把不大于根号 n 的所有素数的倍数剔除,剩下的就是素数。

先用 2 去筛,即把 2 留下,把 2 的倍数剔除掉;把 3 留下,把 3 的倍数剔除掉;…。

时间复杂度:O(n loglogn )

三、欧拉筛法

时间复杂度:O(n)

埃式筛法,同一个数字也许会被筛选多次,比如 6 先被 2 筛选一次,再被 3 筛选一次。欧拉筛法就是在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

用一条语句 if(i % prime[j] == 0) break; 避免了重复筛选的发生。

import java.util.Arrays;public class Prime {/*** 埃拉托斯特尼筛法 VS 欧拉筛法(更优化)*/private static final int MAX_LENGTH_CHECK = 100000000; // 亿private static final int MAX_LENGTH_PRIMES = 10000000; // 千万private static boolean[] check = new boolean[MAX_LENGTH_CHECK]; // 存储标记private static int[] primes = new int[MAX_LENGTH_PRIMES]; // 存储素数/*** 埃拉托斯特尼筛法(简称埃氏筛或爱氏筛):要得到自然数 n 以内的全部素数,必须把不大于 根号 n 的所有素数的倍数剔除,剩下的就是素数。* 例如:给出要筛数值的范围 n,找出以内的素数。* 解法:先用 2 去筛,即把 2 留下,把 2 的倍数剔除掉;再用下一个质数,也就是 3 筛,把 3留下,把3的倍数剔除掉;不断重复下去......。* <p>* 时间复杂度:O(nloglogn)* 不足之处:6 在 i = 2 时被标记,而在 i = 3 时,又被标记了一次。存在重复标记。*/private static void Eratosthenes(int n) {int count = 0;for (int i = 2; i <= n; i++) {// 当 i 不是被剔除的数时,将 i 留下if (!check[i])  primes[count++] = i;// 剔除 i 的倍数for (int j = i + i; j <= n; j += i) check[j] = true;// for (int j = i * i; j <= n; j += i) { // 2 到 i - 1 倍已经筛过,10 万级 i * i 会越界。}}/*** 欧拉筛法:保证每个合数只会被它的最小质因数筛掉,时间复杂度降低到 O(n)。* 每一个数都去乘以当前素数表里面已有的数,当 i 是合数,且 i % primes[j] == 0 时,只能乘以第一个素数 2*/private static void Euler(int n) {int count = 0;for (int i = 2; i <= n; i++) {if (!check[i]) primes[count++] = i;// 每一个数都去乘以当前素数表里面已有的数,如果 i 是合数,且 i % primes[j] == 0,那么它只能乘以第一个素数 2// 如:2×2、3×(2、3)、4×(2)、5×(2、3、5)、6×(2)、7×(2、3、5、7)、8×(2)、9×(2、3)、10×(2)for (int j = 0; j < count; j++) {// 过大的时候跳出if (i * primes[j] > n) break;check[i * primes[j]] = true; // 合数// 如果 i 是一个合数,而且 i % primes[j] == 0// 保证了每个合数只会被它的最小素因子筛掉if (i % primes[j] == 0) break;}}}public static void main(String[] args) {int n = 100000; // 十万long start = System.currentTimeMillis();Eratosthenes(n);long end = System.currentTimeMillis();System.out.println("十万级别数量:埃氏筛,耗时:" + (end - start) + " ms");Arrays.fill(check, false);Arrays.fill(primes, 0);start = System.currentTimeMillis();Euler(n);end = System.currentTimeMillis();System.out.println("十万级别数量:欧拉筛法,耗时:" + (end - start) + " ms");}
}

四、六倍原理

除了 2 和 3 以外,其余素数都与 6 的倍数相邻,也就是也就是说大于 3 的质数一定满足 6n + 1或 6n − 1。

boolean isprime(int n){if (n == 1) return false;else if (n == 2 || n == 3) return true;// 不满足六倍原理,一定不是素数else if (n % 6 != 1 && n % 6 != 5) return false;// 只判断 6 倍的邻数for (int i = 5; i <= sqrt(n); i += 6)if (n % i == 0 || n % (i + 2) == 0)return false;return true;
}

素数筛 Prime sieve相关推荐

  1. prime sieve 素数筛

    index > Algebra > prime sieve 主要内容 本篇只收录较快的线性筛法,作用就是求 2 到 n 的所有素数,顺便得到判断数组. 单纯求素数,标记所有合数.(常用) ...

  2. Prime Number Aizu - 0009(素数筛)

    题意: 给一个数n,问1~n内有多少个素数 题目: Write a program which reads an integer n and prints the number of prime nu ...

  3. Python:实现prime sieve eratosthenes埃拉托斯特尼素数筛选法算法(附完整源码)

    Python:实现prime sieve eratosthenes埃拉托斯特尼素数筛选法算法 # flake8: noqa def prime_sieve_eratosthenes(num):prim ...

  4. 面试官本拿求素数搞我,但被我优雅的“回击“了(素数筛)

    原创公众号(希望能支持一下):bigsai 转载请联系bigsai 文章收录在github 求star 前言 现在的面试官,是无数开发者的梦魇,能够吊打面试官的属实不多,因为大部分面试官真的有那么那几 ...

  5. 筛表合集(素数筛 欧拉函数筛 莫比乌斯函数筛)

    [目录] 一.素数筛 1.素数判断 2.素数普通筛 3.素数线性筛 4.素数区间筛 二.欧拉函数筛 三.莫比乌斯函数筛 [素数筛] 1.直接判定质数 bool judgePrime( int num ...

  6. M - Help Hanzo (大数区间素数筛)

    题目 思路:先对1e5之内的素数筛好,用这些素数筛去大区间内的合数. #include<cstdio> #include<cstring> #include<iostre ...

  7. M - Help Hanzo(模拟素数筛思想+优化)

    题目意思就是求[a,b]的素数个数.这道题我一看枚举不就完了吗? 但是看到那个2^31次方就知道了,如果枚举肯定TLE了: 所以百度了一下说模拟素数筛.我觉得我自己有必要回忆一下素数筛原理. #inc ...

  8. C++实现暴力筛、朴素素数筛、埃氏素数筛、欧拉素数筛的解法

    前言:今天有身边的人在群里吐槽了一道烟台大学OJ上面的水题 然后他提出的问题是:如何开一个1000w大小的数组来存储. What?我仔细看了一眼题目,觉得问题的关键并不是数组可以开多大.而是这是一道在 ...

  9. 素数筛(筛选法求素数)

    求素数 Problem Description 求小于n的所有素数的数量.(素数筛概念) Input 多组输入,输入整数n(n<1000000),以0结束. Output 输出n以内所有素数的个 ...

最新文章

  1. 首次创建maven项目的准备工作
  2. python 操作.mat文件
  3. android源码下载方式
  4. Java语言基本元素
  5. WPF标签页眉控件,其中包含滚动按钮,可移动标签项和每个标签中的关闭按钮
  6. python float精度问题_Python之☞float浮点数精度问题
  7. 取二维数组最大值_学习Java,你必需要知道这些——Java数组
  8. 查看js 执行效率工具
  9. 为什么git的“ pull request”不称为“ push request”?
  10. UEFI学习——使用gRT->GetVariable读取Setup选项值
  11. 搜狗云输入法,实现原理.
  12. latex写加上标题不显示页眉页脚
  13. 蚂蚁金服副总谈区块链
  14. Xmind 2022 Mac思维导图软件
  15. 索骥馆-编程语言之《算法引论-一种创造性方法》扫描版[PDF]
  16. KindEditor插件(富文本编辑器)的使用
  17. 结合进化心理学,解析陌生交友产品的三大问题
  18. 戴尔业务伸向IT服务:佩罗收购毕博背后
  19. 微信小程热映电影导演等数据获取
  20. In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column

热门文章

  1. 基于Python+redis实现的简单推特实现
  2. [ctfshow]终极考核wp
  3. mysql如何实现隔离性_Mysql的隔离以及实现
  4. 夺命雷公狗---DEDECMS----27dedecms电影的下载地址的完成
  5. 数据库调优的几种方法
  6. North American Southeast Regional 2019 (Div 1) D - Swap Free
  7. EBT价值分析,是否能成为上涨传奇?
  8. 最近作项目萌发的疑问
  9. 维度云工业品ERP进销存软件教您如何突破工业品生意的困境?
  10. windows下检测软件运行状态。脚本