质数筛选法
来源:互联网 发布:淘宝会查物流重量吗 编辑:程序博客网 时间:2024/06/05 08:48
近期刷题遇到质数的问题比较多,于是就去搜索了一些关于质数的问题,下面是我的一点总结,就作为学习知识的记录吧。下面是质数筛选的两种方法,学习算法的关键并不仅仅是知道这种方法,更多的是学习算法的思想,学习算法的策略,一个好的策略是非常关键的,它直接影响你算法的效率。
/** * 1.质数筛选法 : * (1)埃拉托色尼筛法(时间复杂度O(nlogn)) * (2)欧拉筛法 (时间复杂度O(n)) * * 2.判断一个数是否是素数:(米勒罗宾测试) * * 3.计算<=n的与n互质的数个数 * * @author MG * */public class Primes { /** * 这个算法叫埃拉托色尼质数筛法(时间复杂度是O(nlogn),比传统方法快速的多) * * 由于一个合数总是可以分解成若干个质数的乘积,那么如果把质数(最初只知道2是质数)的倍数都去掉,那么剩下的就是质数了。 * 例如要查找100以内的质数,首先2是质数,把2的倍数去掉;此时3没有被去掉,可认为是质数,所以把3的倍数去掉; * 再到5,再到7,7之后呢,因为8,9,10刚才都被去掉了,而100以内的任意合数肯定都有一个因子小于10(100的开方), * 所以,去掉,2,3,5,7的倍数后剩下的都是质数了。 * 用程序可以这样解决,引入布尔类型数组a[i],如果i是质数,a[i]=true,否则a[i]=false。 * 那么去掉i可以表示成a[i]=false。 * * @param n */ public static void sieve(int n){ boolean[] assist = new boolean[n]; Arrays.fill(assist, true); for(int i = 2;i < n;i ++){ if(assist[i]){ //注意这从i开始,不用从1开始 for(int j = i * i; j < n;j += i){ assist[j] = false; } } } } /** * 质数欧拉筛法,时间复杂度(O(n) 每个数都会被判断一次) 上面方法中 : 30 在2 * 15 会被筛,在3 * 10也会被筛,在5 * 6 也会被筛(30被重复筛了多次) * * * @param n */ public static int elur(int n){ //标记是否为素数 boolean[] flags = new boolean[n]; int[] primes = new int[n]; int primeIndex = 0; Arrays.fill(flags, true); for(int i = 2; i < n; i++){ if(flags[i]){ primes[primeIndex ++] = i; } for(int j = 0; j < primeIndex; j++){ //判断是否超出范围 if(i * primes[j] > n) break; flags[i * primes[j]] = false; //每个数都是由它最小的质因数过滤掉(这句话很关键) if(i % primes[j] == 0) break; } } return primeIndex == 0 ? 0 : primeIndex - 1; } /** * 假设 b很大,求a * b % n 的结果 * * @param a * @param b * @param n * @return */ public static int getAmulBModN(int a, long b, int n) { int res = 0; while(b != 0){ if((b & 1) == 1) res = (res + a) % n; a = (a + a) % n; b >>= 1; } return res; } /** * b很大,计算a^b % n的值 * * @param a * @param b * @param n * @return */ public static int getAPowerBModN(int a, long b, int n){ int res = 1; while(b != 0) { if((b & 1) == 1) res = getAmulBModN(res, a, n); a = getAPowerBModN(a, a, n); b >>= 1; } return res; } /** * 欧拉函数f(n):计算<=n的与n互质的数的个数 * f(x) = x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有素因数 * * 若m,n互质,f(m * n) = f(m) * f(n) * 特殊性质:当n为奇数时 f(2 * n) = f(n), 证明与上述类似。 * 若n为质数则f(n) = n - 1 * * @param n * @return */ public static int getCount(int n){ int res = n, a = n; for(int i = 2; i * i <= n; i++) { if(a % i == 0) { //防止越界 res = res / i * (i - 1); while(a % i == 0) a /= i; } } //a剩下的如果不为1就肯定为质数 if(a > 1) res = res / a * (a - 1); return res; } /** * 得到1-n的欧拉函数值 * * @param n * @return */ public static int[] getElur(int n){ int[] values = new int[n + 1]; values[1] = 1; //公式中x*(1 - 1/p1)...中的x for(int i = 2;i <= n; i++) { values[i] = i; } for(int i = 2; i <= n; i++){ //values[i] == i : 证明i为质数 if(values[i] == i){ //后面每个都有i这个质因数 for(int j = i; j <= n; j += i){ //先做除法是防止越界 values[j] = values[j] / i * (i - 1); } } } return values; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(getCount(10)); }}
0 0
- 筛选法求质数
- 质数筛选法
- 筛选法(质数)
- 用筛选法求质数
- Eratosthence筛选法(质数)
- PHP筛选法求质数。
- 筛选法求质数(注解)
- Eratosthenes筛选法计算质数
- 用筛选法求质数
- 质数筛选
- 筛选质数
- 算法分析:用筛选法求质数
- 求一亿以内N的质数!筛选法
- 筛选法求质数(素数)
- 数组下标筛选法求质数
- 求质数:筛选法(埃拉托色尼筛法)
- 筛选法求质数(acm)
- Eratosthenes筛选求质数
- git 返回以前版本
- wex5 教程 之 图文讲解 考题模块框架设计
- 14、配置npm国内镜像库
- java Method invoke 参数问题
- 最小生成树——Prim算法
- 质数筛选法
- Mysql 常用 SQL 语句集锦
- Multiple Contexts have a path of "/xxxx"问题解决思路
- 【多线程】多线程编程:线程同步
- ROS机器人Diego 1#制作(十四)机械臂的控制---arduino驱动
- 弹出广告真恶心
- hashmap
- http的get和post发送方法
- android--jni