算法学习第五天

前言:距离上次写博客,已经将近过去十天了,很遗憾没有连续持更博客,因为刚开学手忙脚乱的学习任务,今天终于有空可以静下心来,好好总结一下前天所学的新的算法——埃筛法


统计N以内的素数

素数:只能被1和自身整除的数,01除外  

解法一:暴力算法

直接一个个统计是否可以被除一以外以及自己整除,直接从2开始遍历

public int countPrimes(int n) { 
    int ans = 0; 
    for (int i = 2; i < n; ++i) { 
        ans += isPrime(i) ? 1 : 0; 
    }
        return ans; 
    }//i如果能被x整除,则x/i肯定能被x整除,因此只需判断i和根号x之中较小的即可
 public boolean isPrime(int x) { 
    for (int i = 2; i * i <= x; ++i) { 
        if (x % i == 0) { 
               return false;
                 } 
           }
            return true; 
            }

解法二:埃筛法

利用合数的概念 ( 非素数 ) ,素数 *n 必然是合数,因此可以从 2 开始遍历,将所有的合数做上标记
public static int eratosthenes(int n) { 
    boolean[] isPrime = new boolean[n]; 
    int ans = 0; 
        for (int i = 2; i < n; i++) { 
            if (!isPrime[i]) { 
                ans += 1; 
                for (int j = i * i; j < n; j += i) { 
                        isPrime[j] = true; 
                }
             } 
          }return ans; 
        }

注意:j+=i:相当于逐渐递增系数2

将合数标记为 true j = i * i 2 * i 优化而来,系数 2 会随着遍历递增( j += i ,相当于递增了系数 2 ),
每一个合数都会有两个比本身要小的因子 (0,1 除外 ) 2 * i 必然会遍历到这两个因子
2 递增到大于根号 n 时,其实后面的已经无需再判断(或者只需判断后面一段),而 2 到根号 n 、实际
上在 i 递增的过程中已经计算过了, i 实际上就相当于根号 n
例如: n = 25 会计算以下
2 * 4 = 8
3 * 4 = 12
但实际上 8 12 已经标记过,在 n = 17 时已经计算了 3 * 4 2 * 4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值