素数:只能被1和自身整除的自然数,0,1除外
例如
输入:100
输出:25
提供两种思路:
1:暴力
2:埃筛法
暴力算法不多说,埃筛法思想就是在遍历的过程中,提前把当前遍历的数可能作为因子的合数做一个标记,那么遍历到这个被标记的合数的时候就可以直接跳过。比如遍历到5的时候就把5*n(n为2-正无穷的整数)全部标记为合数。
代码:
import java.util.Scanner;
/**
* n以内素数
* 暴力 埃筛法
*/
public class Sushu {
/**
* 暴力
*/
public static int bf(int n){
int count = 0;//计数
for (int i=2;i<n;i++){
count+=isPrime(i)?1:0;
}
return count;
}
private static boolean isPrime(int i) {
for (int j=2;j*j<=i;j++){//平方是为了优化一部分,避免遍历多余的数据
if (i%j==0){
return false;
}
}
return true;
}
/**
* 埃筛法
* @param n
*/
public static int eratosthenes(int n){
boolean[] isPrime = new boolean[n];//默认都是false false定义都是质数,true定义都是合数(非素数)
int count = 0;//计数
for (int i = 2;i<n;i++){
if (!isPrime[i]){//2和3都是素数,大胆往里面送就行
count++;
for (int j = i*i;j<n;j+=i){//编程技巧 没办法变i,那么就用增加系数就能达到目的了.另外,你画一画图就知道为什么初始值不用2*i而用i*i了
isPrime[j] = true;
}
}
}
return count;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
System.out.println(bf(num));
System.out.println(eratosthenes(num));
}
}
结果