/**
* ref:https://leetcode-cn.com/problems/count-primes/
* 统计所有小于非负整数 n 的质数的数量。
* 示例 1:
* 输入:n = 10
* 输出:4
* 解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
**/
public class CountPrimes {
public static void main(String[] args){
System.out.println(countPrimes(100));
System.out.println(eratosthenes(100));
}
/**
* 统计0~n的质数个数
* @param n
* @return
*/
public static int countPrimes(int n){
int count = 0;
for(int i=2;i<n;i++){
count+= isPrimes(i)?1:0;
}
return count;
}
/**
* 暴力破解法,从2开始遍历,判断是否能被2到自身之间的整除
* 一个数可以整除1和自身的情况下,叫做质数
* @param x
* @return
*/
public static boolean isPrimes(int x){
// 一个整数i如果被x整除,则x/i肯定能被x整除,因此需要判断i到根号x之间值即可。
for(int i=2;i*i<=x;i++){
if(x%i==0){
return false;
}
}
return true;
}
/**
* 埃氏筛法
* 素数判断,可以排除掉合数。既两个素数的积肯定是合数也就是说,不是素数,直接跳转这个数的判断即可
* @param n
* @return
*/
public static int eratosthenes(int n){
// 给每个数的都创建一个对应的标记位,最后统计标记位是素数的个数
boolean[] isPrime = new boolean[n];
int count =0;
// 从2开始迭代,由于1不是素数,不用统计
for(int i=2;i<n;i++){
// 不是合数
if(!isPrime[i]){
// 素数数量统计+1
count++;
// 标识相应的合数,
// 迭代i=2的时候,初始化的值就是2*2=4,然后4+2=6,6+2=8等都就是合数,直至2的计算全部迭代完毕。
// 然后进行下一轮迭代,i=3,初始化的值就是3*3=9,然后9+3=12,12+3=15等继续罗列
for(int j=i*i;j<n;j+=i){
isPrime[j] = true;
}
}
}
return count;
}
}